跳转到主要内容

此包提供了一种简单的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

为了以非阻塞方式执行某些代码

  1. 为某些Python对象创建一个配置了所需worker的Slacker

    from slacker import Slacker
    from slacker.workers import ThreadWorker
    
    class Foo(object):
        # ...
    
    worker = ThreadWorker()
    AsyncFoo = Slacker(Foo, worker)
  2. 构建一个查询(您可以访问属性,进行调用和切片)

    query = AsyncFoo('foo').do_blocking_operation(param1, param2)[0]
  3. 执行查询

    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!

鸣谢

灵感

第三方软件

  • adisp(tornado adisp 实现取自 brukva);

  • 异常序列化工具来自 Ask Solem 的 billiard

许可证

许可证是 MIT。

捆绑的 adisp 库使用 Simplified BSD 许可证。

slacker.serialization 在 BSD 许可证下。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关 安装软件包 的更多信息。

源代码分发

tornado-slacker-0.1.tar.gz (13.2 kB 查看散列

上传于 源码

支持者