This release contains BREAKING changes. Make sure to read and apply upgrade notes.
- [Breaking] Require Ruby
3.1+
. - [Breaking] Remove ability to abort transactions using
throw(:abort)
. Please useraise WaterDrop::Errors::AbortTransaction
. - [Breaking] Disallow (similar to ActiveRecord) exiting transactions with
return
,break
orthrow
. - [Breaking] License changed from MIT to LGPL with an additional commercial option. Note: there is no commercial code in this repository. The commercial license is available for companies unable to use LGPL-licensed software for legal reasons.
- [Enhancement] Make variants fiber safe.
- [Enhancement] In transactional mode do not return any
dispatched
messages as none will be dispatched due to rollback. - [Enhancement] Align the
LoggerListener
async messages to reflect, that messages are delegated to the internal queue and not dispatched. - [Fix] Ensure, that
:dispatched
key for#produce_many_sync
always contains delivery handles (final) and not delivery reports.
Upgrade Notes
PLEASE MAKE SURE TO READ AND APPLY THEM!
throw(:abort)
No Longer Allowed To Abort Transactions
Replace:
producer.transaction do
messages.each do |message|
# Pipe all events
producer.produce_async(topic: 'events', payload: message.raw_payload)
end
# And abort if more events are no longer needed
throw(:abort) if KnowledgeBase.more_events_needed?
end
With:
producer.transaction do
messages.each do |message|
# Pipe all events
producer.produce_async(topic: 'events', payload: message.raw_payload)
end
# And abort if more events are no longer needed
raise(WaterDrop::AbortTransaction) if KnowledgeBase.more_events_needed?
end
return
, break
and throw
No Longer Allowed Inside Transaction Block
Previously, transactions would abort if you exited early using return
, break
, or throw
. This could create unexpected behavior, where users might not notice the rollback or have different intentions. For example, the following would trigger a rollback:
MAX = 10
def process(messages)
count = 0
producer.transaction do
messages.each do |message|
count += 1
producer.produce_async(topic: 'events', payload: message.raw_payload)
# This would trigger a rollback.
return if count >= MAX
end
end
end
This is a source of errors, hence such exits are no longer allowed. You can implement similar flow control inside of your methods that are wrapped in a WaterDrop transaction:
MAX = 10
def process(messages)
producer.transaction do
# Early return from this method will not affect the transaction.
# It will be committed
insert_with_limit(messages)
end
end
def insert_with_limit(messages)
count = 0
messages.each do |message|
count += 1
producer.produce_async(topic: 'events', payload: message.raw_payload)
# This would trigger a rollback.
return if count >= MAX
end
end