Merge pull request #201 from goodboy/single_func_example

Single func example
first_pypi_release
goodboy 2021-02-27 18:04:15 -05:00 committed by GitHub
commit ac30374a15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 124 additions and 9 deletions

View File

@ -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

View File

@ -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)

View File

@ -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",