jeffkreeftmeijer/navvy

Why avoiding Sequel::Model hooks?

Closed this issue · 5 comments

Hello!

I know development on Navvy wasn't active for two years now and my question may be hard to answer because of that.

I found Navvy to suit my needs and want to use it on Heroku. Missing concurrency is no issue for me, due to financial limitations I'll run one worker at most. In order to further save money I'd like to write something like HireFire for Navvy: Hire the worker when there are jobs, else fire him.

My attempt was to write a plugin for the Sequel adapter of Navvy::Job and extend the before_create and after_destroy hooks. It didn't work, so I looked at Navvy's source code. I discovered that Navvy avoids calling hooks of Sequel::Model; it uses insert() instead of create() and delete() instead of destroy().

Could you please explain why this is the case? I don't want to fork Navvy, force it using Sequel hooks and notice it doesn't work as expected.

Thank you very much in advance!

That's been a while, and I can't say I remember. @antekpiechnik, do you?

I forked Navvy and implemented an adapter for Sequel which uses hooks (see former pull request). Then I tried a generic solution and wrote a gem that contains hook methods for before_create, after_update and after_destroy - it should hire or fire the Heroku worker accordingly.

However I ran into the problem that the Sequel hooks seem not to get called correctly by the Navvy::Worker. When I try this

Navvy::Job.plugin( Sklaventreiber::WorkerPlugin )
job = Navvy::Job.create() # calls before_create
job.update( :completed_at => Time.now ) # calls after_update
job.destroy() # calls after_destroy

everything works as expected. But as soon as I do this

Navvy::Job.plugin( Sklaventreiber::WorkerPlugin )
job = Navvy::Job.enqueue( User, :update ) # calls before_create
# no after_update although Job.started() uses Sequel.update()
# no after_destroy although the job completes and is destroyed (job table is empty)

I'm no Ruby expert so it's very possible I fail to notice something, but I'm honestly out of ideas. It would be great if you could take a look at it, @jeffkreeftmeijer , in case you find time and motivation. My tests are here.

Hey Nikolaus,

As you said, it's been two years, so please bear with me. If I understand correctly, you created an after_destroy callback which doesn't get fired when your adapter's Navvy::Job.delete_all gets called. I briefly checked it out and found your adapter is calling Navvy::Job.destroy. While I think that should fire callbacks, it might be possible that something is going wrong there.

I haven't spent much time with Sequel either, so I can't tell you exactly what the problem is, but I think running some small tests on Sequel to see if callbacks are being executed properly would give you some insight on the matter.

Hope that helps, please let me know if you find anything.

Thank you very much for your time! The problem is not only that Navvy::Job.delete_all doesn't call the destroy hooks, but no call to Sequel::Model::update in Navvy::Job fires the appropriate update hook either.

I was hoping it's an obvious solution and I'm just missing something. For now I'll dismiss the generic solution and just add some Heroku worker checks in my application. I have to move on :)

Hey Nikolaus,

Great to hear that you solved the problem. I'll close this issue as I don't have a good insight on the problem right now. If somebody else runs into this, feel free to reopen.