Class: AceMQ::AMQP::Settlement

Inherits:
Object
  • Object
show all
Defined in:
lib/acemq/amqp/interceptors.rb

Overview

What the consumer has decided to do with a delivery, before it does it.

An Ack is what the handler asked for; this is what the retry engine settled on, which is not always the same thing and is the part worth reporting. A handler that asks for a retry on its last attempt is dead-lettered, and a retry that will happen has a delay attached — a number that does not exist until the retry policy has been asked, which is why this is worked out before the interceptors are told rather than guessed from the ack afterwards.

Read it off the ConsumeContext in after_handle:

def after_handle(context, _ack)
record(context.settlement.outcome, context.settlement.delay)
end

The outcomes are the words every AceMQ library writes on a span, and rejected is kept apart from dead_lettered even though both end in the dead-letter queue: a message the handler refused on purpose is the system working, and one that ran out of attempts is not. parked is kept apart from both, because a message nothing could read is a third thing again.

Constant Summary collapse

ACKED =

Acknowledged: the handler was happy.

"acked"
REJECTED =

Refused by the handler, and dead-lettered because of it.

"rejected"
RETRIED =

Going round again, after #delay seconds.

"retried"
DEAD_LETTERED =

Out of attempts, or marked as something retrying cannot fix.

"dead_lettered"
PARKED =

Set aside in {queue}.parked for somebody to look at: the body would not decode, or the handler said the message cannot be read.

"parked"
IN_PROGRESS =

Put back on its own queue after #delay seconds, attempt unchanged, because another consumer holds a live idempotency claim on it. Not a retry and never a dead letter: nobody has failed to handle it yet.

"in_progress"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(outcome:, delay: nil, reason: nil) ⇒ Settlement

Returns a new instance of Settlement.



119
120
121
122
123
124
# File 'lib/acemq/amqp/interceptors.rb', line 119

def initialize(outcome:, delay: nil, reason: nil)
  @outcome = outcome
  @delay = delay
  @reason = reason
  freeze
end

Instance Attribute Details

#delay ⇒ Float? (readonly)

Returns seconds this message will wait, when it is a retry or in progress.

Returns:

  • (Float, nil) —

    seconds this message will wait, when it is a retry or in progress



115
116
117
# File 'lib/acemq/amqp/interceptors.rb', line 115

def delay
  @delay
end

#outcome ⇒ String (readonly)

Returns one of the words above.

Returns:

  • (String) —

    one of the words above



112
113
114
# File 'lib/acemq/amqp/interceptors.rb', line 112

def outcome
  @outcome
end

#reason ⇒ String? (readonly)

Returns why, when it is not going round again.

Returns:

  • (String, nil) —

    why, when it is not going round again



117
118
119
# File 'lib/acemq/amqp/interceptors.rb', line 117

def reason
  @reason
end

Class Method Details

.acked ⇒ Object



126
# File 'lib/acemq/amqp/interceptors.rb', line 126

def self.acked = new(outcome: ACKED)

.dead_lettered(reason) ⇒ Object



129
# File 'lib/acemq/amqp/interceptors.rb', line 129

def self.dead_lettered(reason) = new(outcome: DEAD_LETTERED, reason: reason)

.in_progress(delay) ⇒ Object



131
# File 'lib/acemq/amqp/interceptors.rb', line 131

def self.in_progress(delay) = new(outcome: IN_PROGRESS, delay: delay)

.parked(reason) ⇒ Object



130
# File 'lib/acemq/amqp/interceptors.rb', line 130

def self.parked(reason) = new(outcome: PARKED, reason: reason)

.rejected(reason) ⇒ Object



127
# File 'lib/acemq/amqp/interceptors.rb', line 127

def self.rejected(reason) = new(outcome: REJECTED, reason: reason)

.retried(delay) ⇒ Object



128
# File 'lib/acemq/amqp/interceptors.rb', line 128

def self.retried(delay) = new(outcome: RETRIED, delay: delay)

Instance Method Details

#acked? ⇒ Boolean

Returns:

  • (Boolean)


133
# File 'lib/acemq/amqp/interceptors.rb', line 133

def acked? = @outcome == ACKED

#dead_letters? ⇒ Boolean

Whether the message is going to the dead-letter queue, which a rejection and a give-up both do. Parking is not one of them: it goes to a queue of its own, on purpose.

Returns:

  • (Boolean)


141
# File 'lib/acemq/amqp/interceptors.rb', line 141

def dead_letters? = @outcome == REJECTED || @outcome == DEAD_LETTERED

#in_progress? ⇒ Boolean

Returns:

  • (Boolean)


136
# File 'lib/acemq/amqp/interceptors.rb', line 136

def in_progress? = @outcome == IN_PROGRESS

#parked? ⇒ Boolean

Returns:

  • (Boolean)


135
# File 'lib/acemq/amqp/interceptors.rb', line 135

def parked? = @outcome == PARKED

#retried? ⇒ Boolean

Returns:

  • (Boolean)


134
# File 'lib/acemq/amqp/interceptors.rb', line 134

def retried? = @outcome == RETRIED

#to_s ⇒ Object



143
# File 'lib/acemq/amqp/interceptors.rb', line 143

def to_s = @reason.nil? ? @outcome : "#{@outcome}: #{@reason}"