-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Be able to access headers in work() #12
Comments
Hi Benjamin, The headers were hidden from the developer in order to avoid exposing AMQP internals, so that a developer will work in the mind frame of what he/she already knows with libraries like Sidekiq, Resque and delayed_job. I think it should not be a problem to expose them - however I would like to preserve simplicity. I would be happy to hear what kind of example API you would expect that would serve you best and still be simple. Thanks |
Hi Dotan, that was quick ;-) As the AMQP guide state its good design to use the AMQP metadata headers (http://rubybunny.info/articles/exchanges.html#message_metadata). Usually i keep the user_id and other related information to the actual data in there in the headers key.
The higher up message metadata (routing_key, reply_to, ..) are very useful also sometimes. but it would complicate the access to the headers (2 levels). To keep the interface nice would keep those out of the work() method and instead add a nice interface to make use of them: For example reply() to publish a message to the supplied reply_to key. Kinda like this:
This is pretty much how i usually handle this part, and i was just about to start hacking it into sneakers so i can test it a bit with existing Tasks |
Since i anyway tried it, here is a (running, minimal) example: for this code
|
wow, thanks! I will look into it once I have the time to experiment. I know this might be risking premature optimization - but with the original idea I tried not to create "holder" objects in order to reduce GC overhead, this is why I didn't have the "task" abstraction. However this looks so clean I'm wondering if we can offer both now. |
We could just make it optional, like so:
That would not break the old pattern, but allow for the new one to just add more functionality. |
The API i use now, with a bit less magic:
Rails did not really like the nested classes (autoload magic), and i think explicitly putting it as a setting is nicer anyway if there is more options. The change in worker.rb is also really straight forward for this:
While it allows to add whatever additional data to the Task instance. Sorry its not a pull request, but its so simple i think its ok ;) |
Hey Benjamin, sorry for the blackout, had some personal matters. Trying to allocate time to work on Sneakers issues now 👍 |
So I gave it some research, and I may be wrong, and I wouldn't be surprise if I am, but generating more objects would generate a GC overhead we can do away with. Let's say something like this class MyWorker
include Sneakers::Worker
from_queue :foo
def work_with_params(msg, headers, params)
end
end Then, Sneakers will have to detect which methods the end-user implemented via your What do you think? |
you're welcome to test the new branch, there's working tests for example of a worker and usage :) |
Didn't test it yet but the interface looks fine. If needed everyone can still initialise a task class within the work_with_params method in his code as long as that one as access to it. I will definitely keep using "task-classes" as they make testing the code much easier. |
Thanks, Benjamin, I agree your way of doing things is more encapsulated and cleaner code. I've merged the with_params variant and hope it can support both your use case and others. |
👍 Thanks for this :) |
@jondot is this interface still available? I came across this when googling sneakers and trying to access headers |
@michaelklishin this is perfect, solves half my issue, how can I access headers within my I am desperately trying to find a way to track how many times a message is requeued |
For some cases, that i would like to use sneakers for, i need access to the AMQP headers in the work() method.
Should i just have do_work() hand it through to work()?
This would make it necessary to have work() accept more than one parameter in the future, but i think its the easiest way without changing much else.
The text was updated successfully, but these errors were encountered: