forked from goodboy/tractor
commit
ac30374a15
|
@ -31,6 +31,64 @@ Features
|
||||||
communications protocols, and environment specific IPC primitives
|
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
|
Zombie safe: self-destruct a process tree
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
``tractor`` tries to protect you from zombies, no matter what.
|
``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
|
tree you can imagine; a "worker pool" pattern is a trivial special
|
||||||
case.
|
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.
|
``concurrent.futures.ProcessPoolExecutor`` example for reference.
|
||||||
|
|
||||||
You can run it like so (from this dir) to see the process tree in
|
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!
|
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
|
Install
|
||||||
-------
|
-------
|
||||||
No PyPi release yet!
|
From PyPi::
|
||||||
|
|
||||||
|
pip install tractor
|
||||||
|
|
||||||
|
|
||||||
From git::
|
From git::
|
||||||
|
|
||||||
|
@ -228,6 +289,7 @@ channel`_!
|
||||||
.. _3 axioms: https://en.wikipedia.org/wiki/Actor_model#Fundamental_concepts
|
.. _3 axioms: https://en.wikipedia.org/wiki/Actor_model#Fundamental_concepts
|
||||||
.. _unrequirements: https://en.wikipedia.org/wiki/Actor_model#Direct_communication_and_asynchrony
|
.. _unrequirements: https://en.wikipedia.org/wiki/Actor_model#Direct_communication_and_asynchrony
|
||||||
.. _async generators: https://www.python.org/dev/peps/pep-0525/
|
.. _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
|
.. |gh_actions| image:: https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fgoodboy%2Ftractor%2Fbadge&style=popout-square
|
||||||
|
|
|
@ -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)
|
22
setup.py
22
setup.py
|
@ -24,8 +24,8 @@ with open('docs/README.rst', encoding='utf-8') as f:
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="tractor",
|
name="tractor",
|
||||||
version='0.1.0.alpha0',
|
version='0.1.0a0', # first ever alpha
|
||||||
description='A trionic actor model built on `multiprocessing` and `trio`',
|
description='structured concurrrent "actors"',
|
||||||
long_description=readme,
|
long_description=readme,
|
||||||
license='GPLv3',
|
license='GPLv3',
|
||||||
author='Tyler Goodlet',
|
author='Tyler Goodlet',
|
||||||
|
@ -38,14 +38,23 @@ setup(
|
||||||
'tractor.testing',
|
'tractor.testing',
|
||||||
],
|
],
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'msgpack', 'trio>0.8', 'async_generator', 'colorlog', 'wrapt',
|
'trio>0.8',
|
||||||
'trio_typing', 'pdbpp',
|
'msgpack',
|
||||||
|
'async_generator',
|
||||||
|
'colorlog',
|
||||||
|
'wrapt',
|
||||||
|
'trio_typing',
|
||||||
|
'pdbpp',
|
||||||
],
|
],
|
||||||
tests_require=['pytest'],
|
tests_require=['pytest'],
|
||||||
python_requires=">=3.7",
|
python_requires=">=3.7",
|
||||||
keywords=[
|
keywords=[
|
||||||
"async", "concurrency", "actor model", "distributed",
|
'trio',
|
||||||
'trio', 'multiprocessing'
|
"async",
|
||||||
|
"concurrency",
|
||||||
|
"actor model",
|
||||||
|
"distributed",
|
||||||
|
'multiprocessing'
|
||||||
],
|
],
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 3 - Alpha',
|
'Development Status :: 3 - Alpha',
|
||||||
|
@ -57,6 +66,7 @@ setup(
|
||||||
"Programming Language :: Python :: 3 :: Only",
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
"Intended Audience :: Science/Research",
|
"Intended Audience :: Science/Research",
|
||||||
"Intended Audience :: Developers",
|
"Intended Audience :: Developers",
|
||||||
"Topic :: System :: Distributed Computing",
|
"Topic :: System :: Distributed Computing",
|
||||||
|
|
Loading…
Reference in New Issue