forked from goodboy/tractor
1
0
Fork 0
tractor/docs/README.rst

140 lines
4.5 KiB
ReStructuredText
Raw Normal View History

tractor
*******
The Python async-native multi-core system *you always wanted*.
https://actions-badge.atrox.dev/goodboy/tractor/goto
https://tractor.readthedocs.io/en/latest/?badge=latest
``tractor`` is a `structured concurrent
<https://trio.discourse.group/t/concise-definition-of-structured-concurrency/228>`_
`actor model <https://en.wikipedia.org/wiki/Actor_model>`_” built on
`trio <https://github.com/python-trio/trio>`_ and `multi-processing
<https://en.wikipedia.org/wiki/Multiprocessing>`_.
2020-10-14 15:07:48 +00:00
It is an attempt to pair `trionic
<https://trio.readthedocs.io/en/latest/design.html#high-level-design-principles>`_
`structured concurrency
<https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/>`_
with distributed Python. You can think of it as a ``trio``
2020-12-09 18:01:57 +00:00
*-across-processes* or simply as an opinionated replacement for the
stdlibs ``multiprocessing`` but built on async programming primitives
2020-12-09 18:01:57 +00:00
from the ground up.
2020-10-14 15:07:48 +00:00
Dont be scared off by this description. ``tractor`` **is just
``trio``** but with nurseries for process management and cancel-able
IPC. If you understand how to work with ``trio``, ``tractor`` will
give you the parallelism youve been missing.
2020-12-09 18:01:57 +00:00
``tractor``s nurseries let you spawn ``trio`` *“actors”*: new Python
2020-10-14 15:07:48 +00:00
processes which each run a ``trio`` scheduled task tree (also known as
an `async sandwich
<https://trio.readthedocs.io/en/latest/tutorial.html#async-sandwich>`_
- a call to ``trio.run()``). That is, each “*Actor*” is a new process
plus a ``trio`` runtime.
“Actors” communicate by exchanging asynchronous `messages
<https://en.wikipedia.org/wiki/Message_passing>`_ and avoid sharing
state. The intention of this model is to allow for highly distributed
software that, through the adherence to *structured concurrency*,
results in systems which fail in predictable and recoverable ways.
The first step to grok ``tractor`` is to get the basics of ``trio``
down. A great place to start is the `trio docs
<https://trio.readthedocs.io/en/latest/>`_ and this `blog post
<https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/>`_.
2019-01-21 16:56:33 +00:00
Install
=======
No PyPi release yet!
::
pip install git+git://github.com/goodboy/tractor.git
2020-10-14 15:07:48 +00:00
Alluring Features
=================
* **Its just** ``trio``, but with SC applied to processes (aka
“actors”)
* Infinitely nesteable process trees
* Built-in API for inter-process streaming
2020-10-14 15:07:48 +00:00
* A (first ever?) “native” multi-core debugger for Python using
`pdb++ <https://github.com/pdbpp/pdbpp>`_
2020-10-14 15:07:48 +00:00
* (Soon to land) ``asyncio`` support allowing for “infected” actors
where *trio* drives the *asyncio* scheduler via the astounding
“`guest mode
<https://trio.readthedocs.io/en/stable/reference-lowlevel.html?highlight=guest%20mode#using-guest-mode-to-run-trio-on-top-of-other-event-loops>`_”
2020-12-09 18:01:57 +00:00
The example youre probably after…
==================================
It seems the initial query from most new users is “how do I make a
worker pool thing?”.
``tractor`` is built to handle any SC process tree you can imagine;
the “worker pool” pattern is a trivial special case:
2020-12-09 18:01:57 +00:00
# TODO: workerpool example
.. code::
"""
Run with a process monitor from a terminal using:
$TERM -e watch -n 0.1 "pstree -a $$" & python examples/parallelism/we_are_processes.py && kill $!
"""
from multiprocessing import cpu_count
import os
import tractor
import trio
async def target():
print(f"Yo, i'm '{tractor.current_actor().name}' "
f"running in pid {os.getpid()}")
await trio.sleep_forever()
async def main():
async with tractor.open_nursery() as n:
for i in range(cpu_count()):
await n.run_in_actor(target, name=f'worker_{i}')
print('This process tree will self-destruct in 1 sec...')
await trio.sleep(1)
# you could have done this yourself
raise Exception('Self Destructed')
if __name__ == '__main__':
try:
trio.run(main)
except Exception:
print('Zombies Contained')
2020-12-09 18:01:57 +00:00
2019-01-17 04:19:29 +00:00
Feel like saying hi?
====================
2019-01-17 04:19:29 +00:00
This project is very much coupled to the ongoing development of
2020-09-24 14:04:56 +00:00
``trio`` (i.e. ``tractor`` gets most of its ideas from that brilliant
community). If you want to help, have suggestions or just want to say
hi, please feel free to reach us in our `matrix channel
<https://matrix.to/#/!tractor:matrix.org>`_. If matrix seems too hip,
were also mostly all in the the `trio gitter channel
<https://gitter.im/python-trio/general>`_!