此包提供了一种简单的API,用于将工作从tornado进程/事件循环中移除。
项目描述
此包提供了一种简单的API,用于将工作从tornado进程/事件循环中移除。
当前实现的方法包括
在另一个服务器的http钩子中执行代码(包括Django实现);
在单独的线程中执行代码(使用线程池);
虚拟立即执行。
API示例
from django.contrib.auth.models import User from slacker import adisp from slacker import Slacker from slacker.workers import DjangoWorker AsyncUser = Slacker(User, DjangoWorker()) @adisp.process def process_data(): # all the django ORM is supported; the query will be executed # on remote end, this will not block the IOLoop users = yield AsyncUser.objects.filter(is_staff=True)[:5] print users
(pep-342语法和adisp库是可选的,也支持回调式代码)
安装
pip install tornado-slacker
Slackers和workers
为了以非阻塞方式执行某些代码
为某些Python对象创建一个配置了所需worker的Slacker
from slacker import Slacker from slacker.workers import ThreadWorker class Foo(object): # ... worker = ThreadWorker() AsyncFoo = Slacker(Foo, worker)
构建一个查询(您可以访问属性,进行调用和切片)
query = AsyncFoo('foo').do_blocking_operation(param1, param2)[0]
执行查询
def callback(result): # ... query.proceed(callback)
或者,使用pep-342样式
from slacker import adisp @adisp.process def handler(): result = yield query # ...
Slackers
Slackers是收集操作(属性访问,调用,切片)但不实际执行它们的特殊对象
>>> from slacker import Slacker >>> class Foo(): ... pass ... >>> FooSlacker = Slacker(Foo) >>> FooSlacker.hello.world() __main__.Foo: [('hello',), ('world', (), {})] >>> FooSlacker(name='me').hello.world(1, y=3)[:3] __main__.Foo: [(None, (), {'name': 'me'}), ('hello',), ('world', (1,), {'y': 3}), (slice(None, 3, None), None)]
可调用参数必须是可序列化的。Slackers还提供了一种将收集的操作应用于基对象的方法。
任何可序列化的对象(包括顶级函数和类)都可以包装在Slacker中,例如
from slacker import adisp from slacker import Slacker from slacker.workers import ThreadWorker def task(param1, param2): # do something blocking and io-bound return results async_task = Slacker(task, ThreadWorker()) # pep-342-style @adisp.process def process_data(): results = yield async_task('foo', 'bar') print results # callback style def process_data2(): async_task('foo', 'bar').proceed(on_result) def on_result(results): print results
Python模块也可以是Slackers
import shutil from slacker import Slacker from slacker.workers import ThreadWorker shutil_async = Slacker(shutil, ThreadWorker()) op = shutil_async.copy('file1.txt', 'file2.txt') op.proceed()
Workers
Workers是决定工作和在哪里执行的类
slacker.workers.DummyWorker 在原地执行代码(这是阻塞的);
slacker.workers.ThreadWorker 在线程池中的线程中执行代码;
slacker.workers.HttpWorker 将 slacker 序列化,通过异步 HTTP 请求将数据发送到指定的服务器钩子,并期望它执行代码并返回序列化的结果;
slacker.workers.DjangoWorker 仅仅是带有默认值的 HttpWorker,用于与捆绑的 django 远程服务器钩子实现 (slacker.django_backend) 一起使用。
为了启用 django 钩子,将 'slacker.django_backend.urls' 包含到 urls.py 中,并在 settings.py 中添加 SLACKER_SERVER 选项,并带上服务器地址。
SLACKER_SERVER 默认为 '127.0.0.1:8000',因此对于开发服务器来说,这应该可以直接使用。
并行执行
adisp 库支持并行任务执行。
def _task1(param1, param2): # do something blocking return results def _task2(): # do something blocking return results # worker can be reused worker = ThreadWorker() task1 = Slacker(_task1, worker) task2 = Slacker(_task2, worker) @adisp.process def process_data(): # this will execute task1 and task2 in parallel # and return the result after all data is ready res1, res2 = yield task1('foo', 'bar'), task2() print res1, res2
贡献
如果您有任何建议、错误报告或烦恼,请向问题跟踪器报告。
源代码
欢迎以 hg 或 git 的形式提交 pull request!
鸣谢
灵感
第三方软件
许可证
许可证是 MIT。
捆绑的 adisp 库使用 Simplified BSD 许可证。
slacker.serialization 在 BSD 许可证下。