diff --git a/docs/README.rst b/docs/README.rst index 15abc89..842cbcd 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -313,9 +313,62 @@ real time:: This uses no extra threads, fancy semaphores or futures; all we need 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 + Install ------- From PyPi:: diff --git a/docs/dev_tips.rst b/docs/dev_tips.rst new file mode 100644 index 0000000..96ded0c --- /dev/null +++ b/docs/dev_tips.rst @@ -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. diff --git a/examples/quick_cluster.py b/examples/quick_cluster.py new file mode 100644 index 0000000..ca692a9 --- /dev/null +++ b/examples/quick_cluster.py @@ -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 diff --git a/tractor/_clustering.py b/tractor/_clustering.py index 6d7e7c8..41aaabf 100644 --- a/tractor/_clustering.py +++ b/tractor/_clustering.py @@ -38,7 +38,7 @@ async def open_actor_cluster( uid = tractor.current_actor().uid async def _start(name: str) -> None: - name = f'{name}.{uid}' + name = f'{uid[0]}.{name}' portals[name] = await an.start_actor( enable_modules=modules, name=name,