As someone familiar with asyncio, I don't understand what this is or what it's for. What's an activity, workflow, or worker?
> See the asyncio.sleep in there? That’s no normal local-process sleep; that’s a durable timer backed by Temporal.
That's the normal asyncio.sleep. What does backed by Temporal mean? Reading further, it appears that Temporal is replacing the default asyncio event loop. I don't understand why every third party async Python library/framework feels the need to take over the default event loop instead of just building on top of it.
Temporal is completely above and beyond Asyncio. It's a full scheduling of work and queues that's cross-machine, cross-language, and very transparent.
A workflow is the code that handles only deterministic actions and calls activities.
Activities are functions that do anything you want, typically affecting other systems with network or file calls.
A worker is the running process connected to Temporal with registered workflows & activities for it to pass work to.
I'm doing a lot of work with alert handling and provisioning systems using Temporal. Temporal in two minutes is a great video explanation: https://www.youtube.com/watch?v=f-18XztyN6c
> you only have to get one supergenius to write the hard code to run map and reduce on a global massively parallel array of computers, and all the old code that used to work fine when you just ran a loop still works only it’s a zillion times faster which means it can be used to tackle huge problems in an instant
If you can replace the thing that people use with a distributed version, then that can make it easy to write distributed code.
The thing with event loops in python is that they are not a single, all-governing scheduler (as e.g. in the BEAM).
ev loops instead are a mid-layer concept that sits below other infrastructure such as threads and processes. And (perhaps somewhat frustratingly) it is not too uncommon to have multiple ev loops in parallel. See for example the proxy.py project, which offers to run one async loop per process for a speedup.
As a result, there are some incentives to swap out the loop itself, e.g. for faster implementations like uvloop, because they are somewhat pluggable anyways.
Yes, that is good design and the event loop should basically be shared process-wide (asyncio objects are usually not thread safe and cannot be shared across event loops). Temporal only does custom event loops in isolated workflows.
To add to other responses here, Temporal doesn't take over the default event loop in general (and users still use it for clients and activities and such). Temporal workflows must be deterministic and durable which means they are guaranteed to run and are resumable on other machines. Therefore Temporal workflows specifically operate on a custom event loop implementation. It doesn't affect anything outside the workflow.
The OP seems targeted at devs who are already quite familiar with Temporal and are interested in using the new Python exposure.
FWIW, as someone who has never previously encountered Temporal, and has only a vague sense of the specific problem set it's trying to tackle and architectural approach it has taken, I find the post to be fairly impenetrable.
I'd love to read a proper introduction to Temporal by way of Python (and probably also by comparison to Celery).
I just had to write a Python program that handled multiple async events - from a serial line, and with a tkinter GUI. The only way to make it 'truly' async was to handle the runloops myself, and add a separate queue, onto which I push coroutines, for processing. UI events and Serial I/O events (involving passing of messages to update states on both sides) all have to be pushed through the same mechanism in order to gain the functionality I need.
Sure, I 'could just use asyncio', or somehow work out how to crowbar serial i/o into tkinters' runloop. But in the end, writing my own just made more sense, and more importantly: it works great. I can have serial i/o and UI acting independently, but coordinating through a single queue .. this works so well.
>I don't understand why every third party async Python library/framework feels the need to take over the default event loop instead of just building on top of it.
Because you don't always have what you need to get the crowbar in place, nor big enough leverage to make space for what you have to do, asynchronously, in the app.
But that can indeed just be done with the standard `asyncio` loop. You run your GUI in a thread, run the `asyncio` event loop in its own thread, pass the `asyncio` loop messages with an `asyncio.Queue` and `asyncio.run_coroutine_threadsafe`, and then use `asyncio.to_thread` for the serial communication within the `asyncio` event loop.
> See the asyncio.sleep in there? That’s no normal local-process sleep; that’s a durable timer backed by Temporal.
That's the normal asyncio.sleep. What does backed by Temporal mean? Reading further, it appears that Temporal is replacing the default asyncio event loop. I don't understand why every third party async Python library/framework feels the need to take over the default event loop instead of just building on top of it.