Module: Wurk::Fetcher::Capped

Included in:
Reliable
Defined in:
lib/wurk/fetcher/capped.rb

Overview

Everything the reliable fetcher does differently when one of its queues carries a global concurrency cap (config.global_concurrency).

Prepended onto Reliable, so the separation is structural rather than a claim in a comment: an install that caps nothing resolves one boolean at boot and every fetch pass hands straight back to super — the unchanged loop — without touching another line in this file. The cost of the whole feature to everyone else is that one test and the frame it sits in, which is why rake bench unconfigured and bench/command_count.rb are the gate on this slice rather than an argument about it.

The cap itself — the ledger of who is running what — is QueueSlot and lib/wurk/lua/queue_slot.lua. This is only about fetching under one: asking the question in the same round trip that claims the job, and deciding what a worker does with a queue that says no.

Defined Under Namespace

Classes: Gate

Constant Summary collapse

CAPPED_BACKOFF =

How long a queue that answered "the cluster is at capacity" is skipped locally before this fetcher asks again.

Without it a capped queue sitting at capacity costs a round trip per processor thread per pass, forever — the fetcher spins on a no that cannot change faster than a job finishes somewhere in the cluster. With it the cost is bounded at four questions a second per capped queue for the whole capsule, and the price is that capacity freed on another host is picked up up to a quarter second late. Much shorter and the round trips come back; much longer and a cap starts to behave like a throttle. Not a config knob — a cap is a ceiling on how much runs, never a promise about latency.

0.25
AT_CAPACITY =

The two of fetch_slot.lua's three answers a caller acts on. Its third, 1, means the queue was empty — which costs and means exactly what an empty uncapped queue does, so nothing compares against it.

0
CLAIMED =
2

Instance Method Summary collapse

Instance Method Details

#initialize(capsule) ⇒ Object

Resolved here and never again. The fetch path must not read a config Hash per pass to discover that this install caps nothing, so the answer is a boolean and a Hash of prebuilt gates, both settled while the capsule is materializing its fetcher (Capsule#prepare!).



71
72
73
74
75
76
77
# File 'lib/wurk/fetcher/capped.rb', line 71

def initialize(capsule)
  super
  @gates = capsule.config.global_concurrency.to_h do |name, capacity|
    [name, Gate.new(capacity, Keys.queue_slot(name).freeze, 0.0)]
  end.freeze
  @capped = !@gates.empty?
end