End a run after exactly 12 records, with no time limit: max_events stops the arrival, and the run ends when the last record is written.
Before You Start
The commands run from the root of a clone of the repository, where the files are in docs/snippets/generate-data/. The Full Files block of this page holds the same files, for a reader who saves them by hand.
max_events: 12 is how many times the arrival starts its task in all. An order arrives every 2 seconds, so the 12th arrives at 24 seconds, and the arrival then stops.
sampler=Sampler(seed=42)orders_gap=DistributionConfig(dist="constant",value=2)# The random sequence the blueprint's draw usesorders_gap.stream="arrival.orders"
A Low-level script has no max_events. Its source loops over range(1, 13) and ends after the 12th record.
Leave Out the End Time
The task numbers each order with sequence, so the records show the count. The blueprint has no run section, and the Builder and Low-level files set no until, so the run ends when the last record is written.
order_payload=Template({"order_id":{"gen":"sequence","start":1}},name="tasks.order")@app.task(name="order")deforder(task_id):"""Gives one order record."""returnorder_payload
The run ends with order 12 at 24 seconds. The docs test also runs the model to 1,000 seconds and still gets 12 records, and the Builder file with no until gets 12 too.
# Stop after a count: an arrival that ends after exactly 12 records.## An order arrives every 2 seconds, and `max_events` ends the arrival after 12. The run# has no `until`, so it ends when the last record is written.## Needs: nothing.# Run it with: desflow run docs/snippets/generate-data/stop_after_a_count.yamlsimulation:sim_id:Shopfactor:0random_seed:42logical_start_time:2026-01-01T00:00:00egress:-{type:Console}arrivals:orders:{dist:constant, value:2, spawn:order, max_events:12}tasks:order:payload:order_id:{gen:sequence, start:1}
"""Stop after a count: an arrival that ends after exactly 12 records, builder API.The builder version of `stop_after_a_count.yaml`: an order every 2 seconds, ended by`max_events` after 12.Needs: nothing.Run it with: python docs/snippets/generate-data/stop_after_a_count_builder.py"""importloggingfromdatetimeimportdatetime,timezonefromdesflowimportConsoleEgress,SimulationContextfromdesflow.valuesimportTemplateUNTIL=Nonedefbuild()->SimulationContext:"""Builds the model."""app=SimulationContext(sim_id="Shop",factor=0,random_seed=42,logical_start_time=datetime(2026,1,1,tzinfo=timezone.utc),)app.add_egress(ConsoleEgress())app.add_arrival("orders","constant",value=2,spawn="order",max_events=12)order_payload=Template({"order_id":{"gen":"sequence","start":1}},name="tasks.order")@app.task(name="order")deforder(task_id):"""Gives one order record."""returnorder_payloadreturnappif__name__=="__main__":logging.basicConfig(level=logging.INFO,format="%(levelname)s%(message)s")build().run()
"""Stop after a count: an arrival that ends after exactly 12 records, low-level API.The low-level version of `stop_after_a_count.yaml`: plain SimPy on a`DynamicRealtimeEnvironment`, which publishes each record with `publish_event`. Thearrival loop runs 12 times and then ends, so the run ends when the last record iswritten.Needs: nothing.Run it with: python docs/snippets/generate-data/stop_after_a_count_low_level.py"""importloggingfromdatetimeimportdatetime,timezonefromdesflowimport(ConsoleEgress,DistributionConfig,DynamicRealtimeEnvironment,Sampler,)UNTIL=NoneSTART=datetime(2026,1,1,tzinfo=timezone.utc)ENVIRONMENT:dict={"logical_start_time":START,"timezone":"UTC"}defbuild(env:DynamicRealtimeEnvironment)->None:"""Starts the arrival on `env`."""sampler=Sampler(seed=42)orders_gap=DistributionConfig(dist="constant",value=2)# The random sequence the blueprint's draw usesorders_gap.stream="arrival.orders"deforders_source():fornumberinrange(1,13):yieldenv.timeout(sampler.sample(orders_gap))env.publish_event(f"orders-{number}",{"order_id":number},task="order",instance=number-1,)env.process(orders_source())defrun()->None:"""Runs the model unpaced into the console."""env=DynamicRealtimeEnvironment(factor=0,**ENVIRONMENT)env.setup_egress([ConsoleEgress()])build(env)try:env.run(until=UNTIL)finally:env.teardown()if__name__=="__main__":logging.basicConfig(level=logging.INFO,format="%(levelname)s%(message)s")run()