Module: OMQ::QoS::PullExt
- Defined in:
- lib/omq/qos/routing_ext.rb
Overview
Prepended onto Routing::Pull. At QoS >= 1 every received message is ACK'd back to the sender. At QoS >= 2 the ACK is paired with a dedup-set check: seen digests are ACK'd again but not redelivered to the application.
ACK after successful enqueue into recv_queue. A receiver that
has read a frame off the wire but not yet stored it (because the
app-facing recv_queue is at recv_hwm) has NOT yet taken
responsibility for it — if we ACK'd on wire-receipt and then
crashed before the app dequeued, the sender would have cleared
pending on a message that was effectively lost. ACK-after-enqueue
keeps the at-least-once contract honest and lets recv_hwm
bound truly-in-flight (= read-but-not-stored) messages at zero.
The transform returns nil so the pump's own post-transform
enqueue is skipped — we already enqueued inside the transform.
Instance Method Summary collapse
Instance Method Details
#connection_added(conn) ⇒ Object
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
# File 'lib/omq/qos/routing_ext.rb', line 362 def connection_added(conn) qos = @engine..qos return super if qos.nil? return super if QoS.reliable_transport?(conn) algo = QoS.algo_for(conn) recv_queue = @recv_queue engine = @engine case qos.level when 1 engine.start_recv_pump(conn, recv_queue) do |msg| recv_queue.enqueue(msg) conn.send_command(QoS.ack_command(msg, algorithm: algo)) nil end when 2 dedup = qos.dedup_set_for(conn) QoS.install_qos2_receiver_handler(conn, dedup) engine.start_recv_pump(conn, recv_queue) do |msg| digest = QoS.digest(msg, algorithm: algo) ack = Protocol::ZMTP::Codec::Command.ack(digest, algorithm: algo) if dedup.seen?(digest) conn.send_command(ack) else dedup.add(digest) recv_queue.enqueue(msg) conn.send_command(ack) end nil end when 3 dedup = qos.dedup_set_for(conn) QoS.install_qos2_receiver_handler(conn, dedup) engine.start_recv_pump(conn, recv_queue) do |msg| digest = QoS.digest(msg, algorithm: algo) if dedup.seen?(digest) conn.send_command(Protocol::ZMTP::Codec::Command.comp(digest, algorithm: algo)) else recv_queue.enqueue(QoS::Envelope.new(parts: msg, conn: conn, digest: digest, algo: algo)) end nil end end end |