majek / puka

Puka - the opinionated RabbitMQ client
https://github.com/majek/puka
Other
182 stars 34 forks source link

Add Support for Transactions #2

Closed mankyd closed 13 years ago

mankyd commented 13 years ago

Transactions seem to be one feature the puka is missing. Can this be added?

majek commented 13 years ago

Transactions in AMQP are weird. They are mostly used to ensure the producer that messages indeed were written to disk. Puka achieves this out-of-the-box by using confirms.

Do you have any particular use case for transactions, that is not covered by confirms?

mankyd commented 13 years ago

We are more looking for the rollback feature than for the commit feature, honestly. We want to add things to the queue in the process of a web request, but if the request fails for any particular reason (i.e. exceptions), we want to be able to rollback the things that were added.

majek commented 13 years ago

Interesting. Are you sending messages to multiple queues? What happens if the request goes away after the commit?

mankyd commented 13 years ago

Potentially, yes, multiple things will be sent to an exchange (or multiple things to multiple exchanges, etc). We have something similar for a database, where ever web request is wrapped inside a transaction. It's at a relatively high level in our web request stack; there's not much that can fail after the transaction is committed. If something does go wrong after the commit, well, so be it – we tried our best :)

majek commented 13 years ago

Right, now I understand. What you want to do is, more or less:

0) http request received 1) open transaction, publish multiple messages 2) do some database operations, or something else potentially expensive 3) check if the http request is still alive and decide to rollback or commit

We could add a command, something like "basic_publish_multi()" which opens a transaction, publishes a list of messages and returns a handle which you could commit or rollback. Implementing that is not going to be trivial.

Would this approach suit you?

mankyd commented 13 years ago

That would work. It's worth noting that we plan on publishing to the exchange(s) in different places in our code (i.e. different features have different uses for queues). Ideally, we'd just stick with the basic_publish (though we could certainly work with a basic_publish_mutli). We can certainly maintain a list of handles that need to be committed, but I believe that AMQP only requires one tx.commit to commit multiple publishes:

http://www.rabbitmq.com/amqp-0-9-1-quickref.html#tx.commit

Could this not be implemented by simply adding Client.select, Client.commit, and Client.rollback?

majek commented 13 years ago

Could this not be implemented by simply adding Client.select, Client.commit, and Client.rollback?

In a normal client, like Pika yes, it could (and probably is already), but Puka doesn't expose channels to the user and transactions are channel-scoped. Thus a need to handle scope separately and that why it's going to be non trivial.