繁体   English   中英

在所有线程中重新加载python模块

[英]Reloading python module in all threads

我在Django上编写了一些内容管理系统。 用户可以创建具有各种URL的页面。 对于页面路由,我使用默认的django url路由器机制:

pages = CMSHelpers().get_available_pages()

urlpatterns = patterns(
    '',
    url(r'^$', include('app.home.site.urls', namespace='homepage')),
    url(r'^search/', include('app.search.site.urls', namespace='search')),
    url(r'^ajax/', include('app.ajax.site.urls', namespace='ajax')),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

for page in pages:
    if page.module.slug:
        try:
            urlpatterns += patterns(
                '',
                url(
                    '^%s/' % page.url.strip('/'),
                    include(
                        'app.%s.site.urls' % page.module.slug,
                        namespace=page.module.slug + '-' + page.module_params
                    ),
                    kwargs={'page_data': page}
                )
            )
            logging.debug("Imported url %s for module %s" % (page.url.strip('/'), page.module.slug))
        except ImportError:
            logging.debug("Cannot import urls.py for module %s" % page.module.slug)
            continue
    else:
        continue

urlpatterns += patterns('',
    url(r'^captcha/', include('captcha.urls')),
)

问题:

django应用启动时,python缓存所有urlpatterns。 当用户通过CMS更改某些页面的url时,我正在重新加载urlpatterns, 但仅适用于当前uwsgi进程/线程

    urlconf = settings.SUBDOMAIN_URLCONFS["www"]
    clear_url_caches()
    reload(sys.modules[urlconf])
    reloaded = import_module(urlconf)
    if hasattr(reloaded, 'urlpatterns'):
        reloaded_urls = getattr(reloaded, 'urlpatterns')
        set_urlconf(tuple(reloaded_urls))

因此,当用户尝试在网站上访问此页面时,会收到随机404错误。

那么,如何为所有uwsgi进程/线程重新加载模块?

将用户创建的模式保存到数据库。

编写一些填充URL模式的中间件,以在每个页面请求上进行搜索。

然后,您可以根据需要拥有多个线程。 我怀疑开销可以忽略不计。

鉴于此类Web应用程序通常使用“无共享”架构,因此在每个请求上检查某种类型的外部数据存储实际上是合理的。 所述外部数据存储区可以具有更新时间戳,每个工作线程/进程将其与自己的上次更新时间戳进行比较,并决定在较新的模块时重新加载模块。

但是,一种更好的方法是为r'^(?P<url>.*)/$'类的页面添加一个包含所有内容的网址格式,并将其路由到单个处理程序,该处理程序查找特定页面的处理程序应为并调用它。

我遇到了同样的问题。 我不想在每个丢失的URL上访问数据库。 我只想在发生更改时重新加载URL。

由于我们使用uwsgi来运行所有django进程,因此我将通过向Hwsgi进程发送HUP信号来强制从Shell重新加载。

在Django进程中,我只想向父进程(即uwsgi进程)发送HUP信号。 所以我添加了这两行来做到这一点:

    import os, signal

    os.kill( os.getppid(), signal.SIGHUP )

我希望这有帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM