PyWorker VS module PyWorker & MPWorker #2052
Replies: 4 comments 11 replies
-
@ntoll @mchilvers I have actually found an issue with the <script type="mpy" async>
from pyscript import document, PyWorker
worker = PyWorker("./test.py", type="pyodide")
await worker.ready
document.body.append(await worker.sync.greetings())
</script> in test.py: from pyscript import sync
def greetings():
return "Hello from Pyodide"
sync.greetings = greetings As a result, whenever the worker is ready that promise gets resolved and you can interact out of the box with whatever utility pyodide exported in the
|
Beta Was this translation helpful? Give feedback.
-
I think @ntoll hit the nail on the head of my thoughts! I've put together an imaginary/fantasy app of my first idea of what I would like to do to have a simple app that has a main thread in mp, and a worker using pyodide to do some long running task... https://pyscript.com/@mchilvers/workers-fantasy/latest Of course, I have no idea whether it would be technically feasible or not(!). |
Beta Was this translation helpful? Give feedback.
-
Here's a summary of what we discussed. You can kick off a named worker like this: <script src="./main.py" type="mpy" async></script>
<script src="./worker.py" type="py" worker="fred"></script> In my from pyscript import workers
# Do a bunch of UI boilerplate here...
...
# Check until an individual worker is running. Returns the `sync` object.
fred = await workers["fred"]
# We're all up and running, so go do stuff with the worker.
meaning_of_life = await fred.deep_thought() # returns 42 ;-) ALL THE BELOW IS FOR FURTHER LATER DISCUSSION: Here's how we register the function... from pyscript import sync
def deep_thought():
time.sleep(millions_of_years)
return 42
# Currently we do this... BUT...
sync.deep_thought = deep_thought
# This is the idiomatic Python way to do the above.
__ALL__ = [deep_thought, ...] Also, can we make the signature of instantiating the <script src="./worker.py" type="py" worker="fred"></script> Is the same as..? fred = PyWorker(src="./worker.py", type="py") |
Beta Was this translation helpful? Give feedback.
-
My initial thoughts were that as a writer of PyScript applications, my mental model is as follows:
The above has the benefit of offering (I think!) a consistent way for PyScript app developers to use workers. @WebReflection, you mentioned that there are reasons why a worker created via a <script> element is not and should not the same as a worker created through the PyWorker API, but I don't quite understand that yet. Is it a technical reason (as in possible/not possible) or are there certain use cases where one or the other could provide different functionality. Regardless of that discussion, using the 'workers' collection obviously raises some questions:
|
Beta Was this translation helpful? Give feedback.
-
We currently have 3 different ways to create a "PyWorker":
@pyscript/core
module we export bothPyWorker
andMPWorker
to disambiguate between the two interpreters, read the right config and bring in the correct hooks out of the boxPyWorker
which doesn't do anything like the module exports and it requires mandatory options to specify the interpretertype
, theconfig
to use, and so on ... nothing is inferred but, most notably, there are no defaults and there is noMPWorker
counterpart ... any PyWorker via Python code needs to create references viaPyWorker(url, { "type": "pyodide" })
orPyWorker(url, { "type": "micropython" })
and I am not sure this is the best we can doOn top of that, the JS module exports need to be awaited because they need to bootstrap the whole thing so that
sync
in there can work, as well as plugins resolved and the defaultsync
attached to thexworker
reference, which is also resolved later on, once the interpreter is ready.On the other hand, the polyscript
XWorker
generic constructor accepts atype
to specify the interpreter, but in PyScript thetype
is usually eitherpy
ormpy
and we ask our users to specify atype
that is the interpreter name instead ... I find all this a bit confusing and, even if properly documented, I wonder what we could do to improve the Python side of affair.We have at least 2 options:
type
is inferred, so that<script type="py">from pyscript import PyWorker; PyWorker(url)</script>
would, by default, create a pyodideXWorker
and, as we recently introduced thepyscript.config
it's also easy to pass along that too, if the same config is desired.mpy
on main would likely bootstrap a pyodide worker, when needed, not an micropython one ... so it's practically counter-intuitive. On top of this, it doesn't reflect the JS exports with explicit names to disambiguate the used interpreter and its conifgMPWorker
to thepyscript
namespace, so thatPyWorker
by default uses pyodide, unless explicitly different, andMPWorker
will always be micropython ... we bring theconfig
in per each environment, if not specified otherwise, so we'll have a more 1:1 behavior with the exported JS counterpart, still without needing toawait
those references like we do in JSI don't know what would be the most "Pythonic" way forward, all I know is that I don't currently like neither the JS nor the Python behavior around workers, but we need to
await
on the JS side, although I really don't like theMPWorker
as a name, yet I also don't like the fact in Python we need to always specify atype
as interpreter name ... I think we could be smarter in both worlds than what we have now, but I also don't want to break the JS side of affair as that's been requested and successfully used already by various developers and breaking it would be, and feel, both sad/bad and unnecessary.What do you folks think? @ntoll @fpliger @JeffersGlass
Beta Was this translation helpful? Give feedback.
All reactions