此包提供了一种简单的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 许可证下。