You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Motor与多Sanic Worker兼容性疑问及相关实践咨询

Can Motor be used with multiple Sanic workers?

Great question! Let's break this down clearly for you:

Why a naive setup causes problems

First, let's recap how Sanic's multi-worker mode works: it forks the main process to spawn worker processes. As Motor's docs explicitly state, it doesn't support forking or multi-threading—it’s built for single-threaded Tornado environments where the IOLoop and connection resources are isolated to one process.

If you initialize a Motor client in the main process before Sanic forks workers, all workers will end up sharing the same underlying socket connections and IOLoop state. This leads to all sorts of unpredictable behavior: connection drops, data corruption, deadlocks, or requests hanging indefinitely. Motor’s internals simply aren’t designed to handle shared resources across separate processes.

Yes, developers have tried this (and there are proven solutions)

The key fix is to initialize Motor separately in each worker process, not in the main process before forking. Here are the most common, community-vetted approaches:

  • Initialize Motor in a post-fork listener
    Sanic provides listeners that run after each worker finishes starting up. Use the after_server_start listener to create your Motor client instance per worker. This ensures every worker gets its own isolated connection pool and IOLoop association.
    Example code snippet:
    from sanic import Sanic
    from sanic.response import json
    from motor.motor_asyncio import AsyncIOMotorClient
    
    app = Sanic("MotorSanicApp")
    
    @app.listener("after_server_start")
    async def setup_motor(app, loop):
        # Create a unique Motor client for this worker
        app.ctx.mongo_client = AsyncIOMotorClient("mongodb://localhost:27017")
        app.ctx.db = app.ctx.mongo_client.my_database
    
    @app.route("/get-document")
    async def fetch_doc(request):
        doc = await request.app.ctx.db.test_collection.find_one()
        return json({"document": doc})
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=8000, workers=4)
    
  • Avoid global Motor instances
    Never create a Motor client at the module level (which runs in the main process). Instead, create it within the worker’s context—either via the listener above, or lazy-initialize it when the first request hits the worker.

Community feedback

Plenty of Sanic developers have successfully used Motor with multiple workers using these patterns. You’ll find discussions in Sanic’s GitHub issues, Reddit threads, and community forums where folks share their working setups. The core takeaway is simple: never share a Motor client across forked processes; let each worker manage its own client instance.

内容的提问来源于stack exchange,提问作者CarlJogenburg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:37:39