The Fireworks Show
The Fireworks Show: choreography IS concurrency. A show is three staggered volleys and then a finale - five shells that must burst TOGETHER, which is only physically possible if someone can light five fuses at once. We run the same score twice: once with a single igniter (the intern), once with a full crew (the fiber scheduler), and the burst timeline itself is the argument. You cannot sequence your way to a finale.
Scheduling & Concurrency
Round 18
Samuel Williams
exit 0
bundle exec ruby examples/fireworks_show.rb
a real captured run
THE FIREWORKS SHOW (you cannot sequence your way to a finale)
one igniter, lighting fuses in a row (685ms):
willow *
peony *
comet *
chrysanth *
crossette *
strobe *
palm *
ring *
fish *
finale-1 #
finale-2 #
finale-3 #
finale-4 #
finale-5 #
full crew, same score (216ms):
willow *
comet *
peony *
crossette *
chrysanth *
strobe *
palm *
fish *
ring *
finale-1 #
finale-2 #
finale-3 #
finale-4 #
finale-5 #
finale spread: intern 204ms (a sad trickle of #-marks)
crew 1ms (one vertical WALL of sky)
show length: intern 685ms vs crew 216ms
(650ms of total fuse burned either way - parallel isn't
faster fire, it's fire arranged in TIME)
the score is a plan: volleys are dependency layers (volley 2
waits on volley 1 - that's rhythm), and the finale is a fan-in
that must OVERLAP, which no amount of sequential diligence can
produce. the scheduler isn't an optimization here; it's the
performance itself. async is usually sold as throughput -
requests per second, workers kept busy. the finale is the purer
case: five things that must happen AT ONCE, and the only tool
that can say 'at once' is the one holding all five fuses.
source
# frozen_string_literal: true # The Fireworks Show: choreography IS concurrency. A show is three # staggered volleys and then a finale - five shells that must burst # TOGETHER, which is only physically possible if someone can light # five fuses at once. We run the same score twice: once with a # single igniter (the intern), once with a full crew (the fiber # scheduler), and the burst timeline itself is the argument. You # cannot sequence your way to a finale. # # bundle exec ruby examples/fireworks_show.rb # # Runs offline; exits 1 unless the crewed finale is simultaneous # AND the intern's provably wasn't. require class="s">"bundler/setup" require class="s">"agentic" Agentic.logger.level = class="y">:fatal def mono = Process.clock_gettime(Process:class="y">:CLOCK_MONOTONIC) VOLLEYS = [ [{name: class="s">"willow", fuse: 0.04}, {name: class="s">"peony", fuse: 0.05}, {name: class="s">"comet", fuse: 0.04}], [{name: class="s">"chrysanth", fuse: 0.05}, {name: class="s">"crossette", fuse: 0.04}, {name: class="s">"strobe", fuse: 0.05}], [{name: class="s">"palm", fuse: 0.04}, {name: class="s">"ring", fuse: 0.05}, {name: class="s">"fish", fuse: 0.04}] ].freeze FINALE = 5.times.map { |i| {name: class="s">"finale-#{i + 1}", fuse: 0.05} }.freeze def run_show(crew_size) orchestrator = Agentic:class="y">:PlanOrchestrator.new(concurrency_limit: crew_size) t0 = mono bursts = {} previous_volley = [] VOLLEYS.each_with_index do |volley, v| previous_volley = volley.map do |shell| task = Agentic:class="y">:Task.new(description: shell[class="y">:name], agent_spec: {class="s">"name" => shell[class="y">:name], class="s">"instructions" => class="s">"fly"}) orchestrator.add_task(task, previous_volley, agent: ->(_t) { sleep(shell[class="y">:fuse]) bursts[shell[class="y">:name]] = {volley: v, at: mono - t0} class="y">:boom }) task end end FINALE.each do |shell| task = Agentic:class="y">:Task.new(description: shell[class="y">:name], agent_spec: {class="s">"name" => shell[class="y">:name], class="s">"instructions" => class="s">"fly"}) orchestrator.add_task(task, previous_volley, agent: ->(_t) { sleep(shell[class="y">:fuse]) bursts[shell[class="y">:name]] = {volley: class="y">:finale, at: mono - t0} class="y">:BOOM }) end orchestrator.execute_plan [bursts, mono - t0] end def timeline(bursts, duration, label) cols = 56 puts class="s">" #{label} (#{(duration * 1000).round}ms):" bursts.sort_by { |_, b| b[class="y">:at] }.each do |name, b| col = (b[class="y">:at] / duration * (cols - 1)).round mark = (b[class="y">:volley] == class="y">:finale) ? class="s">"#" : class="s">"*" puts class="s">" #{name.ljust(10)} #{" class="s">" * col}#{mark}" end end def finale_spread(bursts) times = bursts.select { |_, b| b[class="y">:volley] == class="y">:finale }.map { |_, b| b[class="y">:at] } times.max - times.min end puts class="s">"THE FIREWORKS SHOW (you cannot sequence your way to a finale)" puts intern_bursts, intern_time = run_show(1) crew_bursts, crew_time = run_show(8) timeline(intern_bursts, intern_time, class="s">"one igniter, lighting fuses in a row") puts timeline(crew_bursts, crew_time, class="s">"full crew, same score") puts intern_spread = finale_spread(intern_bursts) crew_spread = finale_spread(crew_bursts) total_fuse = (VOLLEYS.flatten + FINALE).sum { |s| s[class="y">:fuse] } puts class="s">" finale spread: intern #{(intern_spread * 1000).round}ms (a sad trickle of #-marks)" puts class="s">" crew #{(crew_spread * 1000).round}ms (one vertical WALL of sky)" puts class="s">" show length: intern #{(intern_time * 1000).round}ms vs crew #{(crew_time * 1000).round}ms" puts class="s">" (#{(total_fuse * 1000).round}ms of total fuse burned either way - parallel isn't" puts class="s">" faster fire, it's fire arranged in TIME)" puts puts class="s">" the score is a plan: volleys are dependency layers (volley 2" puts class="s">" waits on volley 1 - that's rhythm), and the finale is a fan-in" puts class="s">" that must OVERLAP, which no amount of sequential diligence can" puts class="s">" produce. the scheduler isn't an optimization here; it's the" puts class="s">" performance itself. async is usually sold as throughput -" puts class="s">" requests per second, workers kept busy. the finale is the purer" puts class="s">" case: five things that must happen AT ONCE, and the only tool" puts class="s">" that can say 'at once' is the one holding all five fuses." crewed_wall = crew_spread < 0.02 intern_trickle = intern_spread > crew_spread * 3 exit((crewed_wall && intern_trickle) ? 0 : 1)