Class: AceMQ::AMQP::Patterns::Pipeline
- Inherits:
-
Object
- Object
- AceMQ::AMQP::Patterns::Pipeline
- Defined in:
- lib/acemq/amqp/patterns/routing_slip.rb
Overview
A route declared once, that messages travel by name.
orders = Patterns::Pipeline.new("orders", %w[validate charge ship])
mq.apply(orders.topology)
mq.consume(orders.queue_for("charge"), &orders.follow(mq) do ||
charge(.payload)
end)
orders.start(mq, { "order_id" => "A-1" })
The other half of RoutingSlip, and the half Java has. A slip carries its destinations; a pipeline knows them, and the message carries only the step names and how far along it is. That is three short headers instead of a JSON document, and a route that reads in a management console without decoding anything — at the price of a route that is the same for every message and has to be declared on both ends.
The naming is Java's, exactly. The exchange is the pipeline's name
and is direct, the routing key is the step name, and the queue behind a
step is pipeline.step. A Ruby consumer that got any of those wrong
would be listening where no Java service publishes, so they are not
arranged for Ruby's convenience.
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#steps ⇒ Object
readonly
Returns the value of attribute steps.
Instance Method Summary collapse
-
#exchange ⇒ Object
The exchange every step of this pipeline is published to.
-
#follow(connection) ⇒ Object
follow_slip bound to this pipeline.
-
#initialize(name, steps) ⇒ Pipeline
constructor
A new instance of Pipeline.
-
#queue_for(step) ⇒ Object
The queue behind a step.
-
#slip ⇒ Object
A fresh slip at the start of this route, in the declared form.
-
#start(connection, payload, **fields) ⇒ Envelope
Sends a payload into the first step.
-
#step_named(step) ⇒ Object
One of this pipeline's steps, as a Step that knows where to publish.
- #to_s ⇒ Object
-
#topology ⇒ Topology
The exchange, the queues and the bindings this pipeline needs.
Constructor Details
#initialize(name, steps) ⇒ Pipeline
Returns a new instance of Pipeline.
344 345 346 347 348 349 350 351 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 344 def initialize(name, steps) @name = name.to_s @steps = Array(steps).map(&:to_s) raise ArgumentError, "a pipeline needs a name" if @name.empty? raise ArgumentError, "pipeline #{@name} needs at least one step" if @steps.empty? freeze end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
340 341 342 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 340 def name @name end |
#steps ⇒ Object (readonly)
Returns the value of attribute steps.
340 341 342 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 340 def steps @steps end |
Instance Method Details
#exchange ⇒ Object
The exchange every step of this pipeline is published to.
354 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 354 def exchange = @name |
#follow(connection) ⇒ Object
AceMQ::AMQP::Patterns.follow_slip bound to this pipeline.
395 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 395 def follow(connection, &) = Patterns.follow_slip(connection, pipeline: self, &) |
#queue_for(step) ⇒ Object
The queue behind a step.
361 362 363 364 365 366 367 368 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 361 def queue_for(step) unless @steps.include?(step.to_s) raise ArgumentError, "pipeline #{@name} has no step called '#{step}'. Its steps are " \ "#{@steps.join(", ")}." end "#{@name}.#{step}" end |
#slip ⇒ Object
A fresh slip at the start of this route, in the declared form.
384 385 386 387 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 384 def slip RoutingSlip.new(steps: @steps.map { |step| step_for(step) }, form: RoutingSlip::ROUTE, pipeline: self) end |
#start(connection, payload, **fields) ⇒ Envelope
Sends a payload into the first step.
392 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 392 def start(connection, payload, **fields) = slip.start(connection, payload, **fields) |
#step_named(step) ⇒ Object
One of this pipeline's steps, as a Step that knows where to publish.
400 401 402 403 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 400 def step_named(step) queue_for(step) step_for(step.to_s) end |
#to_s ⇒ Object
405 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 405 def to_s = "Pipeline[#{@name}: #{@steps.join(" -> ")}]" |
#topology ⇒ Topology
The exchange, the queues and the bindings this pipeline needs.
A Topology to apply rather than declarations made here, so it composes with whatever else a service declares and is applied once at start-up like everything else.
377 378 379 380 381 |
# File 'lib/acemq/amqp/patterns/routing_slip.rb', line 377 def topology @steps.reduce(Topology.new.exchange(@name, "direct")) do |built, step| built.queue(queue_for(step)).binding(queue_for(step), @name, step) end end |