Carrier Quotes
Carrier Quotes: the most common integration problem in commerce - ask three shipping carriers for rates, and cope with the fact that on any given afternoon one is slow, one is down, and one has quietly changed its response format. The confident-code answer: ALL defensiveness lives at the boundary. Each carrier adapter converts whatever happened - success, timeout, garbage - into an object with the same face (a Quote or an Unavailable), so the core that compares and chooses …
Reliability & Recovery
Round 20
Avdi Grimm
exit 0
bundle exec ruby examples/carrier_quotes.rb
a real captured run
CARRIER QUOTES (confidence is suspicion, spent once, at the door)
an ordinary afternoon (one slow, one down, one confused):
TurtleShip: $8.99 in 5d
FedUp: unavailable (no answer within 50ms)
ParcelPanic: unavailable (malformed response: [:cost, :eta])
-> checkout shows: TurtleShip: $8.99 in 5d (2 carriers degraded, sale not lost)
the apocalypse (every carrier asleep):
-> checkout shows: FlatRate fallback: $12.0 in 7d (fallback: true - the store stays OPEN)
the architecture in one sentence: quote_from is the only method
allowed to be afraid. it converts every real-world outcome -
timeout, schema drift, exception - into an object with the same
FACE (available?, cents, to_s), so choose_rate reads like the
business rule it is: pick the cheapest available, fall back to
flat rate, never lose the sale. the degraded carriers keep their
REASONS (ops will want them), the fan-out means the slow carrier
never delays the fast one, and nil - the billion-dollar
non-answer - is stopped at the door like it should be. timid
code checks everything everywhere; confident code has a
doorman.
source
# frozen_string_literal: true # Carrier Quotes: the most common integration problem in commerce - # ask three shipping carriers for rates, and cope with the fact that # on any given afternoon one is slow, one is down, and one has # quietly changed its response format. The confident-code answer: # ALL defensiveness lives at the boundary. Each carrier adapter # converts whatever happened - success, timeout, garbage - into an # object with the same face (a Quote or an Unavailable), so the core # that compares and chooses contains not one nil check, not one # rescue, not one question mark it didn't want. Timid code asks # "but what if?" at every line; confident code asks it ONCE, at the # door. # # bundle exec ruby examples/carrier_quotes.rb # # Runs offline; exits 1 unless checkout survives every weather. require class="s">"bundler/setup" require class="s">"agentic" Agentic.logger.level = class="y">:fatal Quote = Struct.new(class="y">:carrier, class="y">:cents, class="y">:days) do def available? = true def to_s = class="s">"#{carrier}: $#{cents / 100.0} in #{days}d" end Unavailable = Struct.new(class="y">:carrier, class="y">:reason) do def available? = false def cents = Float:class="y">:INFINITY def to_s = class="s">"#{carrier}: unavailable (#{reason})" end BUDGET = 0.05 # The carriers, as found in nature CARRIERS = { class="s">"TurtleShip" => -> { sleep(0.01) {price_cents: 899, transit_days: 5} }, class="s">"FedUp" => -> { sleep(0.2) {price_cents: 1499, transit_days: 1} }, # asleep at the desk class="s">"ParcelPanic" => -> { {cost: class="s">"cheap!!", eta: class="s">"soon"} } # changed their API. again. }.freeze # The boundary: one adapter, all the suspicion in the file def quote_from(carrier, raw_call) raw = nil thread = Thread.new { raw = raw_call.call } unless thread.join(BUDGET) thread.kill return Unavailable.new(carrier, class="s">"no answer within #{(BUDGET * 1000).round}ms") end cents = raw[class="y">:price_cents] days = raw[class="y">:transit_days] return Unavailable.new(carrier, class="s">"malformed response: #{raw.keys.inspect}") unless cents.is_a?(Integer) && days.is_a?(Integer) Quote.new(carrier, cents, days) rescue => e Unavailable.new(carrier, class="s">"adapter caught: #{e.class}") end # The core: reads like the business rule it is. No nils survive to here. def choose_rate(quotes) available = quotes.select(&class="y">:available?) return {choice: Quote.new(class="s">"FlatRate fallback", 1200, 7), degraded: quotes, fallback: true} if available.empty? {choice: available.min_by(&class="y">:cents), degraded: quotes.reject(&class="y">:available?), fallback: false} end def fetch_quotes(carriers) orchestrator = Agentic:class="y">:PlanOrchestrator.new(concurrency_limit: 3) tasks = carriers.to_h do |name, api| task = Agentic:class="y">:Task.new(description: name, agent_spec: {class="s">"name" => name, class="s">"instructions" => class="s">"quote"}) orchestrator.add_task(task, agent: ->(_t) { quote_from(name, api) }) [name, task] end result = orchestrator.execute_plan tasks.values.map { |t| result.task_result(t.id).output } end puts class="s">"CARRIER QUOTES (confidence is suspicion, spent once, at the door)" puts quotes = fetch_quotes(CARRIERS) verdict = choose_rate(quotes) puts class="s">" an ordinary afternoon (one slow, one down, one confused):" quotes.each { |q| puts class="s">" #{q}" } puts class="s">" -> checkout shows: #{verdict[class="y">:choice]} (#{verdict[class="y">:degraded].size} carriers degraded, sale not lost)" puts apocalypse = fetch_quotes(CARRIERS.transform_values { -> { sleep(0.2) } }) end_times = choose_rate(apocalypse) puts class="s">" the apocalypse (every carrier asleep):" puts class="s">" -> checkout shows: #{end_times[class="y">:choice]} (fallback: #{end_times[class="y">:fallback]} - the store stays OPEN)" puts failures = [] failures << class="s">"wrong quote chosen" unless verdict[class="y">:choice].carrier == class="s">"TurtleShip" && verdict[class="y">:choice].cents == 899 failures << class="s">"degradation reasons lost" unless verdict[class="y">:degraded].map(&class="y">:reason).join.match?(/no answer/) && verdict[class="y">:degraded].map(&class="y">:reason).join.match?(/malformed/) failures << class="s">"apocalypse broke checkout" unless end_times[class="y">:fallback] && end_times[class="y">:choice].cents == 1200 failures << class="s">"a nil escaped the boundary" if quotes.any?(&class="y">:nil?) || apocalypse.any?(&class="y">:nil?) puts class="s">" the architecture in one sentence: quote_from is the only method" puts class="s">" allowed to be afraid. it converts every real-world outcome -" puts class="s">" timeout, schema drift, exception - into an object with the same" puts class="s">" FACE (available?, cents, to_s), so choose_rate reads like the" puts class="s">" business rule it is: pick the cheapest available, fall back to" puts class="s">" flat rate, never lose the sale. the degraded carriers keep their" puts class="s">" REASONS (ops will want them), the fan-out means the slow carrier" puts class="s">" never delays the fast one, and nil - the billion-dollar" puts class="s">" non-answer - is stopped at the door like it should be. timid" puts class="s">" code checks everything everywhere; confident code has a" puts class="s">" doorman." exit(failures.empty? ? 0 : 1)