Class: Mammoth::DeliveryProgressCoordinator
- Inherits:
-
Object
- Object
- Mammoth::DeliveryProgressCoordinator
- Defined in:
- lib/mammoth/delivery_progress_coordinator.rb
Overview
Coordinates durable delivery progress across out-of-order workers.
Work is registered in source order before dispatch. Completion may arrive in any order, but a checkpoint and upstream acknowledgement advance only when every item in the oldest closed source group has a durable outcome. A source group is normally one PostgreSQL transaction.
Defined Under Namespace
Instance Attribute Summary collapse
-
#checkpoint_store ⇒ Object
readonly
Returns the value of attribute checkpoint_store.
-
#publication_name ⇒ Object
readonly
Returns the value of attribute publication_name.
-
#slot_name ⇒ Object
readonly
Returns the value of attribute slot_name.
-
#source_name ⇒ Object
readonly
Returns the value of attribute source_name.
Instance Method Summary collapse
-
#complete(work) ⇒ String?
Mark a work item durably resolved and advance all newly contiguous groups.
-
#finalize ⇒ String?
Close and advance a final source group after a clean end-of-stream.
-
#initialize(checkpoint_store:, source_name:, slot_name:, publication_name:, acknowledger: nil, position_resolver: nil) ⇒ DeliveryProgressCoordinator
constructor
A new instance of DeliveryProgressCoordinator.
-
#register(work, group_end:) ⇒ void
Register work before dispatch.
Constructor Details
#initialize(checkpoint_store:, source_name:, slot_name:, publication_name:, acknowledger: nil, position_resolver: nil) ⇒ DeliveryProgressCoordinator
Returns a new instance of DeliveryProgressCoordinator.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/mammoth/delivery_progress_coordinator.rb', line 47 def initialize(checkpoint_store:, source_name:, slot_name:, publication_name:, acknowledger: nil, position_resolver: nil) @checkpoint_store = checkpoint_store @source_name = source_name @slot_name = slot_name @publication_name = publication_name @acknowledger = acknowledger @position_resolver = position_resolver # rubocop:disable Layout/LeadingCommentSpace -- Steep inline type syntax requires `#:`. @groups = [] #: Array[Group] @entries_by_work = {} #: Hash[untyped, Array[Entry]] # rubocop:enable Layout/LeadingCommentSpace @entries_by_work.compare_by_identity @mutex = Mutex.new end |
Instance Attribute Details
#checkpoint_store ⇒ Object (readonly)
Returns the value of attribute checkpoint_store.
39 40 41 |
# File 'lib/mammoth/delivery_progress_coordinator.rb', line 39 def checkpoint_store @checkpoint_store end |
#publication_name ⇒ Object (readonly)
Returns the value of attribute publication_name.
39 40 41 |
# File 'lib/mammoth/delivery_progress_coordinator.rb', line 39 def publication_name @publication_name end |
#slot_name ⇒ Object (readonly)
Returns the value of attribute slot_name.
39 40 41 |
# File 'lib/mammoth/delivery_progress_coordinator.rb', line 39 def slot_name @slot_name end |
#source_name ⇒ Object (readonly)
Returns the value of attribute source_name.
39 40 41 |
# File 'lib/mammoth/delivery_progress_coordinator.rb', line 39 def source_name @source_name end |
Instance Method Details
#complete(work) ⇒ String?
Mark a work item durably resolved and advance all newly contiguous groups.
83 84 85 86 87 88 89 90 91 |
# File 'lib/mammoth/delivery_progress_coordinator.rb', line 83 def complete(work) @mutex.synchronize do entry = pending_entry_for(work) raise ReplicationError, "delivery progress completed before registration" unless entry entry.completed = true advance_contiguous_groups end end |
#finalize ⇒ String?
Close and advance a final source group after a clean end-of-stream.
96 97 98 99 100 101 |
# File 'lib/mammoth/delivery_progress_coordinator.rb', line 96 def finalize @mutex.synchronize do @groups.last.closed = true if @groups.last advance_contiguous_groups end end |
#register(work, group_end:) ⇒ void
This method returns an undefined value.
Register work before dispatch.
68 69 70 71 72 73 74 75 76 77 |
# File 'lib/mammoth/delivery_progress_coordinator.rb', line 68 def register(work, group_end:) @mutex.synchronize do group = current_group entry = Entry.new(work: work, source_position: source_position(work), completed: false) group.items << entry (@entries_by_work[work] ||= []) << entry # steep:ignore group.closed = true if group_end end nil end |