Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: goodboy/tractor
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7647c56d5c529092edc8e260526c71219f4c6bce
Choose a base ref
..
head repository: goodboy/tractor
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f9f73974709794fea38aec3cf768a3644ecb46ac
Choose a head ref
Showing with 128 additions and 13 deletions.
  1. +65 −3 docs/README.rst
  2. +43 −0 examples/parallelism/single_func.py
  3. +20 −10 setup.py
68 changes: 65 additions & 3 deletions docs/README.rst
Original file line number Diff line number Diff line change
@@ -31,6 +31,64 @@ Features
communications protocols, and environment specific IPC primitives


Run a func in a process
-----------------------
Use ``trio``'s style of focussing on *tasks as functions*:

.. code:: python
"""
Run with a process monitor from a terminal using::
$TERM -e watch -n 0.1 "pstree -a $$" \
& python examples/parallelism/single_func.py \
&& kill $!
"""
import os
import tractor
import trio
async def burn_cpu():
pid = os.getpid()
# burn a core @ ~ 50kHz
for _ in range(50000):
await trio.sleep(1/50000/50)
return os.getpid()
async def main():
async with tractor.open_nursery() as n:
portal = await n.run_in_actor(burn_cpu)
# burn rubber in the parent too
await burn_cpu()
# wait on result from target function
pid = await portal.result()
# end of nursery block
print(f"Collected subproc {pid}")
if __name__ == '__main__':
trio.run(main)
This runs ``burn_cpu()`` in a new process and reaps it on completion
of the nursery block.

If you only need to run a sync function and retreive a single result, you
might want to check out `trio-parallel`_.


Zombie safe: self-destruct a process tree
-----------------------------------------
``tractor`` tries to protect you from zombies, no matter what.
@@ -150,7 +208,7 @@ pool thing?"*.
tree you can imagine; a "worker pool" pattern is a trivial special
case.

We have a `full re-implementation <worker_pool>`_ of the std-lib's
We have a `full worker pool re-implementation`_ of the std-lib's
``concurrent.futures.ProcessPoolExecutor`` example for reference.

You can run it like so (from this dir) to see the process tree in
@@ -164,11 +222,14 @@ This uses no extra threads, fancy semaphores or futures; all we need
is ``tractor``'s IPC!


.. _worker_pool: 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
-------
No PyPi release yet!
From PyPi::

pip install tractor


From git::

@@ -228,6 +289,7 @@ channel`_!
.. _3 axioms: https://en.wikipedia.org/wiki/Actor_model#Fundamental_concepts
.. _unrequirements: https://en.wikipedia.org/wiki/Actor_model#Direct_communication_and_asynchrony
.. _async generators: https://www.python.org/dev/peps/pep-0525/
.. _trio-parallel: https://github.com/richardsheridan/trio-parallel


.. |gh_actions| image:: https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fgoodboy%2Ftractor%2Fbadge&style=popout-square
43 changes: 43 additions & 0 deletions examples/parallelism/single_func.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
Run with a process monitor from a terminal using::
$TERM -e watch -n 0.1 "pstree -a $$" \
& python examples/parallelism/single_func.py \
&& kill $!
"""
import os

import tractor
import trio


async def burn_cpu():

pid = os.getpid()

# burn a core @ ~ 50kHz
for _ in range(50000):
await trio.sleep(1/50000/50)

return os.getpid()


async def main():

async with tractor.open_nursery() as n:

portal = await n.run_in_actor(burn_cpu)

# burn rubber in the parent too
await burn_cpu()

# wait on result from target function
pid = await portal.result()

# end of nursery block
print(f"Collected subproc {pid}")


if __name__ == '__main__':
trio.run(main)
30 changes: 20 additions & 10 deletions setup.py
Original file line number Diff line number Diff line change
@@ -24,8 +24,8 @@

setup(
name="tractor",
version='0.1.0.alpha0',
description='A trionic actor model built on `multiprocessing` and `trio`',
version='0.1.0a0', # first ever alpha
description='structured concurrrent "actors"',
long_description=readme,
license='GPLv3',
author='Tyler Goodlet',
@@ -38,25 +38,35 @@
'tractor.testing',
],
install_requires=[
'msgpack', 'trio>0.8', 'async_generator', 'colorlog', 'wrapt',
'trio_typing', 'pdbpp',
'trio>0.8',
'msgpack',
'async_generator',
'colorlog',
'wrapt',
'trio_typing',
'pdbpp',
],
tests_require=['pytest'],
python_requires=">=3.7",
keywords=[
"async", "concurrency", "actor model", "distributed",
'trio', 'multiprocessing'
'trio',
"async",
"concurrency",
"actor model",
"distributed",
'multiprocessing'
],
classifiers=[
'Development Status :: 3 - Alpha',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)'
'Operating System :: POSIX :: Linux',
"Development Status :: 3 - Alpha",
"Operating System :: POSIX :: Linux",
"Operating System :: Microsoft :: Windows",
"Framework :: Trio",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Intended Audience :: Science/Research",
"Intended Audience :: Developers",
"Topic :: System :: Distributed Computing",