commit
08fa55a8c3
|
@ -313,9 +313,62 @@ real time::
|
||||||
This uses no extra threads, fancy semaphores or futures; all we need
|
This uses no extra threads, fancy semaphores or futures; all we need
|
||||||
is ``tractor``'s IPC!
|
is ``tractor``'s IPC!
|
||||||
|
|
||||||
|
To be extra terse the ``tractor`` devs have started hacking some "higher
|
||||||
|
level" APIs for managing actor trees/clusters. These interfaces should
|
||||||
|
generally be condsidered provisional for now but we encourage you to try
|
||||||
|
them and provide feedback. Here's a new API that let's you quickly
|
||||||
|
spawn a flat cluster:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
import trio
|
||||||
|
import tractor
|
||||||
|
|
||||||
|
|
||||||
|
async def sleepy_jane():
|
||||||
|
uid = tractor.current_actor().uid
|
||||||
|
print(f'Yo i am actor {uid}')
|
||||||
|
await trio.sleep_forever()
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
'''
|
||||||
|
Spawn a flat actor cluster, with one process per
|
||||||
|
detected core.
|
||||||
|
|
||||||
|
'''
|
||||||
|
portal_map: dict[str, tractor.Portal]
|
||||||
|
results: dict[str, str]
|
||||||
|
|
||||||
|
# look at this hip new syntax!
|
||||||
|
async with (
|
||||||
|
|
||||||
|
tractor.open_actor_cluster(
|
||||||
|
modules=[__name__]
|
||||||
|
) as portal_map,
|
||||||
|
|
||||||
|
trio.open_nursery() as n,
|
||||||
|
):
|
||||||
|
|
||||||
|
for (name, portal) in portal_map.items():
|
||||||
|
n.start_soon(portal.run, sleepy_jane)
|
||||||
|
|
||||||
|
await trio.sleep(0.5)
|
||||||
|
|
||||||
|
# kill the cluster with a cancel
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
trio.run(main)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
.. _full worker pool re-implementation: https://github.com/goodboy/tractor/blob/master/examples/parallelism/concurrent_actors_primes.py
|
.. _full worker pool re-implementation: https://github.com/goodboy/tractor/blob/master/examples/parallelism/concurrent_actors_primes.py
|
||||||
|
|
||||||
|
|
||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
From PyPi::
|
From PyPi::
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
Hot tips for ``tractor`` hackers
|
||||||
|
================================
|
||||||
|
|
||||||
|
This is a WIP guide for newcomers to the project mostly to do with
|
||||||
|
dev, testing, CI and release gotchas, reminders and best practises.
|
||||||
|
|
||||||
|
``tractor`` is a fairly novel project compared to most since it is
|
||||||
|
effectively a new way of doing distributed computing in Python and is
|
||||||
|
much closer to working with an "application level runtime" (like erlang
|
||||||
|
OTP or scala's akka project) then it is a traditional Python library.
|
||||||
|
As such, having an arsenal of tools and recipes for figuring out the
|
||||||
|
right way to debug problems when they do arise is somewhat of
|
||||||
|
a necessity.
|
||||||
|
|
||||||
|
|
||||||
|
Making a Release
|
||||||
|
----------------
|
||||||
|
We currently do nothing special here except the traditional
|
||||||
|
PyPa release recipe as in `documented by twine`_. I personally
|
||||||
|
create sub-dirs within the generated `dist/` with an explicit
|
||||||
|
release name such as `alpha3/` when there's been a sequence of
|
||||||
|
releases I've made, but it really is up to you how you like to
|
||||||
|
organize generated sdists locally.
|
||||||
|
|
||||||
|
|
||||||
|
.. _documented by twine: https://twine.readthedocs.io/en/latest/#using-twine
|
||||||
|
|
||||||
|
|
||||||
|
Debugging and monitoring actor trees
|
||||||
|
------------------------------------
|
||||||
|
TODO: but there are tips in the readme for some terminal commands
|
||||||
|
which can be used to see the process trees easily on Linux.
|
||||||
|
|
||||||
|
|
||||||
|
Using the log system to trace `trio` task flow
|
||||||
|
----------------------------------------------
|
||||||
|
TODO: the logging system is meant to be oriented around
|
||||||
|
stack "layers" of the runtime such that you can track
|
||||||
|
"logical abstraction layers" in the code such as errors, cancellation,
|
||||||
|
IPC and streaming, and the low level transport and wire protocols.
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
import trio
|
||||||
|
import tractor
|
||||||
|
|
||||||
|
|
||||||
|
async def sleepy_jane():
|
||||||
|
uid = tractor.current_actor().uid
|
||||||
|
print(f'Yo i am actor {uid}')
|
||||||
|
await trio.sleep_forever()
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
'''
|
||||||
|
Spawn a flat actor cluster, with one process per
|
||||||
|
detected core.
|
||||||
|
|
||||||
|
'''
|
||||||
|
portal_map: dict[str, tractor.Portal]
|
||||||
|
results: dict[str, str]
|
||||||
|
|
||||||
|
# look at this hip new syntax!
|
||||||
|
async with (
|
||||||
|
|
||||||
|
tractor.open_actor_cluster(
|
||||||
|
modules=[__name__]
|
||||||
|
) as portal_map,
|
||||||
|
|
||||||
|
trio.open_nursery() as n,
|
||||||
|
):
|
||||||
|
|
||||||
|
for (name, portal) in portal_map.items():
|
||||||
|
n.start_soon(portal.run, sleepy_jane)
|
||||||
|
|
||||||
|
await trio.sleep(0.5)
|
||||||
|
|
||||||
|
# kill the cluster with a cancel
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
trio.run(main)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
|
@ -38,7 +38,7 @@ async def open_actor_cluster(
|
||||||
uid = tractor.current_actor().uid
|
uid = tractor.current_actor().uid
|
||||||
|
|
||||||
async def _start(name: str) -> None:
|
async def _start(name: str) -> None:
|
||||||
name = f'{name}.{uid}'
|
name = f'{uid[0]}.{name}'
|
||||||
portals[name] = await an.start_actor(
|
portals[name] = await an.start_actor(
|
||||||
enable_modules=modules,
|
enable_modules=modules,
|
||||||
name=name,
|
name=name,
|
||||||
|
|
Loading…
Reference in New Issue