How do I setup a callback for on success that spans across projects?

50 views
Skip to first unread message

Altonymous

unread,
Jun 4, 2015, 3:21:00 PM6/4/15
to sid...@googlegroups.com
I have Project A which needs to create a batch for Project B to process.  When Project B work is complete I want it to call a worker in Project A.  I'm not sure the correct syntax to make this happen?  It seems that batches is expecting all the workers to exist in the same project.

My only alternative thought is to have Project A enqueue work for Project B asynchronously, and when Project B is done asynchronously call a job in Project A.  In other words not rely on batching at all.


Thoughts?  Suggestions?

Mike Perham

unread,
Jun 4, 2015, 3:30:09 PM6/4/15
to sid...@googlegroups.com
Your success callback in B should create a job in A.  You can push a Sidekiq job to another Redis or another namespace as explained here:


Mike

--
You received this message because you are subscribed to the Google Groups "Sidekiq" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sidekiq+u...@googlegroups.com.
To post to this group, send email to sid...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sidekiq/5d428c2f-7b51-4515-8d07-72135cbc540b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Mike Perham – CEO, Contributed Systems
Smart, effective open source infrastructure for your apps.

Chris Altman

unread,
Jun 4, 2015, 3:53:22 PM6/4/15
to sid...@googlegroups.com
Not sure I explained myself correctly.  the on_success is in a batch created by Project A, my expectation is that it should fire when the worker in Project B finishes.  Are you suggesting that I do what I was suggesting in my alternative idea.. which is to have Project B call Project A directly when it's done?  These are using the same redis.  The issue is that Project B is trying to initialize a class in Project A.. and since it doesn't have that class it fails.



Mike Perham

unread,
Jun 4, 2015, 3:59:56 PM6/4/15
to sid...@googlegroups.com
Oh, I see.  Are you using different namespaces for the different projects?

Batches can't cross Redis boundaries.  Sounds like you are creating a batch in A which has jobs designed to be processed by B?  That won't work unless they are using the same Redis config.  Jobs created in Batch A in Redis A must be processed by Sidekiqs from project A.


For more options, visit https://groups.google.com/d/optout.

Chris Altman

unread,
Jun 4, 2015, 4:06:11 PM6/4/15
to sid...@googlegroups.com
They are both in the same redis and the same namespace.  They are just under two different projects.  i.e. 2 different processes on two different machines.



Mike Perham

unread,
Jun 4, 2015, 4:18:10 PM6/4/15
to sid...@googlegroups.com
Ok, do you use named queues to ensure A's sidekiqs don't try to process B's jobs?

Sharing callback code between projects is very tricky.  Perhaps you can create a generic callback handler which can push a job targeted at A:

batch = Sidekiq::Batch.new
batch.on(:success, GenericHandler, 'class' => 'AWorker', 'queue' => 'queueA', 'args' => [])

# This class must be in A and B
class GenericHandler
  def on_success(status, options)
    Sidekiq::Client.push(options)
  end
end

Now the callback can be processed by either A or B but the result will get back to A.

Mike


For more options, visit https://groups.google.com/d/optout.

Chris Altman

unread,
Jun 4, 2015, 5:13:52 PM6/4/15
to sid...@googlegroups.com
Mike,

Yes we used name queues to ensure the projects don't process each other's work.  I will give the GenericHandler a try.  Gotta run for now so I won't be able to give a status update, but I'll ask a co-worker to chime in after he tests out the code, or I'll give an update tomorrow.

Chris Altman

unread,
Jun 5, 2015, 5:00:41 PM6/5/15
to sid...@googlegroups.com
Mike,

Thanks for the help, that appears to get us moving again.  Wish there was a cleaner way to do it, but what works, works... :P

Scott Steele

unread,
Jun 5, 2015, 5:07:00 PM6/5/15
to sid...@googlegroups.com
Thanks for the suggestion. Improves my mental model / understanding of how batch callbacks work.

We did need to tweak it a little bit so that a method other than AWorker#perform would be called:

In the AWorker class:

class AWorker
  # ...
  def some_method
    batch = Sidekiq::Batch.new
    batch.on(
      :success, GenericHandler,
      'class' => 'AWorker::OnSuccess',
      'queue' => 'queueA',
      'args' => [argX, argY, argZ]
    )
    # ...
  end

  class OnSuccess < AWorker
    def perform(x, y, z)
      # ...
    end
  end
end
Reply all
Reply to author
Forward
0 new messages