@@ -35,31 +35,38 @@ import duron
3535from duron.contrib.storage import FileLogStorage
3636
3737
38+ # Effects encapsulate side effects (I/O, randomness, API calls)
3839@duron.effect
3940async def work (name : str ) -> str :
4041 print (" ⚡ Preparing to greet..." )
41- await asyncio.sleep(2 ) # Simulate I/O
42+ await asyncio.sleep(2 )
4243 print (" ⚡ Greeting..." )
4344 return f " Hello, { name} ! "
4445
4546
4647@duron.effect
4748async def generate_lucky_number () -> int :
4849 print (" ⚡ Generating lucky number..." )
49- await asyncio.sleep(1 ) # Simulate I/O
50+ await asyncio.sleep(1 )
5051 return random.randint(1 , 100 )
5152
5253
54+ # Durable functions orchestrate workflow logic via ctx.run()
55+ # They're deterministically replayed from logs on resume
5356@duron.durable
5457async def greeting_flow (ctx : duron.Context, name : str ) -> str :
58+ # Run effects concurrently - results are logged for replay
5559 message, lucky_number = await asyncio.gather(
56- ctx.run(work, name), ctx.run(generate_lucky_number)
60+ ctx.run(work, name),
61+ ctx.run(generate_lucky_number),
5762 )
5863 return f " { message} Your lucky number is { lucky_number} . "
5964
6065
6166async def main ():
67+ # Session manages execution and log storage
6268 async with duron.Session(FileLogStorage(Path(" log.jsonl" ))) as session:
69+ # Starts new workflow or resumes from existing log
6370 task = await session.start(greeting_flow, " Alice" )
6471 result = await task.result()
6572 print (result)
@@ -71,4 +78,5 @@ if __name__ == "__main__":
7178
7279## Next steps
7380
74- Read the [ getting started guide] ( https://brian14708.github.io/duron/getting-started/ ) .
81+ - Read the [ getting started guide] ( https://brian14708.github.io/duron/getting-started/ )
82+ - Explore a more advanced example with streams and signals: [ examples/agent.py] ( https://github.com/brian14708/duron/blob/main/examples/agent.py )
0 commit comments