如果我创建一个芹菜节拍时间表,使用timedelta(days=1),第一个任务将在24小时后进行,引用芹菜节拍文件:
使用timedelta进行计划意味着任务将以30秒的间隔发送(第一个任务将在芹菜节拍开始后30秒发送,然后在最后一次运行后每30秒发送一次).
但事实是,在很多情况下,调度程序在启动时运行任务实际上很重要,但是我没有找到允许我在芹菜启动后立即运行任务的选项,我不仔细阅读,或者芹菜错过了这个功能吗?
本周我遇到了这个非常有趣的问题,最好从一些事实开始:
pylibmc是不是线程安全的Django的memcached的后端使用时,直接在外壳启动多个Django的实例时并发请求命中会崩溃.python-memcached,它也会解决这个问题,但这个问题与此无关.从第一个事实开始,这是我如何重现这个pylibmc问题:
pylibmc我有一个django应用程序,它执行了很多memcached读取和写入,并且有这个部署策略,我在shell中启动多个django进程,绑定到不同的端口(8001,8002),并使用nginx来进行平衡.
我对这两个django实例启动了两个单独的负载测试,使用locust,这就是发生的事情:

在上面的屏幕截图中,他们都崩溃并报告完全相同的问题,如下所示:
断言"ptr-> query_id == query_id +1"对于函数"memcached_get_by_key"失败,可能是"程序员错误,query_id没有递增.",在libmemcached/get.cc:107
所以在上面的例子中,我们了解到对memcached via的多线程并发请求pylibmc可能会导致问题,这在某种程度上不会影响uWSGI多个工作进程.
为了证明这一点,我从uWSGI以下设置开始:
master = true
processes = 2
Run Code Online (Sandbox Code Playgroud)
这告诉uWSGI启动两个工作进程,然后告诉nginx服务器任何django静态文件,并路由非静态请求uWSGI,看看会发生什么.在服务器启动的情况下,我在localhost中对django启动了相同的蝗虫测试,并确保每秒有足够的请求来引发对memcached的并发请求,结果如下:

在uWSGI控制台中,没有死工人进程的迹象,并且没有工作人员重新生成,但是查看屏幕截图的上半部分,肯定有并发请求(5.6 req/s).
我非常好奇如何uWSGI让它消失,我无法在他们的文档中了解到,回顾一下,问题是:
uWSGI是如何管理工作进程的,因此多线程memcached请求不会导致django崩溃?
事实上,我甚至不确定这是uWSGI管理工作者进程以避免这个问题的方式,还是其他一些魔术随之而来uWSGI的伎俩,我在他们的文档中看到了一些名为memcached路由器的东西明白,这有关系吗?
在我看来,这是一个非常有用的重新映射,因为您几乎从不单独键入 control,为什么不将其重新映射到 esc?
由于 karabiner 消失了,我一直在尝试使用hammerspoon 恢复我最喜欢的功能,我认为这可以实现,但我无法使其正常工作,有人知道如何正确执行此操作吗?
函数tornado.ioloop.PeriodicCallback(callback, callback_time, io_loop=None)说我无法为我的callback函数添加参数,但是如果我真的需要callback用参数调用呢?有工作吗?
测试 Flask 应用程序时,该celery_worker装置不起作用,因为 celery 附带的 pytest 装置不在 Flask 应用程序上下文中运行。
# tasks.py
@current_app.task(bind=True)
def some_task(name, sha):
return Release.query.filter_by(name=name, sha=sha).all()
# test_celery.py
def test_some_celery_task(celery_worker):
async_result = some_task.delay(default_appname, default_sha)
assert len(async_result.get()) == 0
Run Code Online (Sandbox Code Playgroud)
上面的测试将简单地抛出RuntimeError: No application found.并拒绝运行。
通常,当在 Flask 项目中使用 celery 时,我们必须继承celery.Celery并修补该__call__方法,以便实际的 celery 任务将在 Flask 应用程序上下文中运行,如下所示:
def make_celery(app):
celery = Celery(app.import_name)
celery.config_from_object('citadel.config')
class EruGRPCTask(Task):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return super(EruGRPCTask, self).__call__(*args, **kwargs)
celery.Task = EruGRPCTask
celery.autodiscover_tasks(['citadel'])
return celery
Run Code Online (Sandbox Code Playgroud)
使用“Command + Number”之类的东西来改变分割窗格的焦点非常方便,比使用箭头键或类似的东西在窗格之间循环要好得多。
但我没有找到任何选项让 iterm2 告诉我每个窗格的编号,这将使在拆分窗格太多时无法使用窗格编号切换窗格。
我uint64在我的DataFrame中有一个列,但是当我将该DataFrame转换为python dict的列表时DataFrame.to_dict('record'),以前的内容uint64会被神奇地转换为float:
In [24]: mid['bd_id'].head()
Out[24]:
0 0
1 6957860914294
2 7219009614965
3 7602051814214
4 7916807114255
Name: bd_id, dtype: uint64
In [25]: mid.to_dict('record')[2]['bd_id']
Out[25]: 7219009614965.0
In [26]: bd = mid['bd_id']
In [27]: bd.head().to_dict()
Out[27]: {0: 0, 1: 6957860914294, 2: 7219009614965, 3: 7602051814214, 4: 7916807114255}
Run Code Online (Sandbox Code Playgroud)
我该如何避免这种奇怪的行为?
奇怪的是,如果我使用to_dict()而不是to_dict('records'),bd_id列将是int类型:
In [43]: mid.to_dict()['bd_id']
Out[43]:
{0: 0,
1: 6957860914294,
2: 7219009614965,
...
Run Code Online (Sandbox Code Playgroud) python ×4
celery ×2
celerybeat ×1
django ×1
flask ×1
hammerspoon ×1
iterm2 ×1
karabiner ×1
macos-sierra ×1
nginx ×1
pandas ×1
pytest ×1
tornado ×1
uwsgi ×1