Синхронно четене на многочастно качване заедно с Django

Имам приложение Django, което трябва да има достъп до четене на качени файлове от много части като файлоподобни обекти както са качени, което означава, че имам нужда от повече или по-малко синхронен достъп до обекта на заявката и начин за да го разопаковате на парчета в двоични данни. Django за съжаление обработва качванията, като ги премества директно в паметта или във временни файлове, което няма да работи за моя случай на употреба.

Някой препоръча да използвам gevent/greenlet, за да се справя с качването, но не съм сигурен как това се отразява на уравнението и каква настройка е необходима заедно с Django, за да работи. Плюс това, стартирането на нещо извън Django би означавало, че ще трябва да внедря слой за връзка с база данни, за да потвърдя, че качването е разрешено (използвайки идентификатор на билет).

С това казано, как мога да настроя това? Django трябва да работи в WSGI приложение и някой също препоръча написването на второ WSGI приложение за улавяне на единичен URL път за качване. Бих искал по същество да се възползвам възможно най-много от рамката на Django, като същевременно мога да чета качвания синхронно?

(Току-що се запознах с библиотеката requests Python и трябва да кажа, че съм доста голям фен, въпреки че нямам представа за използването й в контекст на сървър.)


person Naftuli Kay    schedule 22.02.2013    source източник


Отговори (2)


Вярвам, че много от тези предложения усложняват нещата прекалено много.

Трябва да промените начина, по който Django обработва качените файлове? Просто променете манипулатора за качване.

базовият клас е относително ясен, и ви дава много страхотни куки. Трябва да можете да го разширите, за да правите това, което искате.

person Hamms    schedule 04.03.2013
comment
Трябва да имам RTFM. Длан на лицето. - person Naftuli Kay; 05.03.2013
comment
Ха-ха, получава най-доброто от нас. - person Hamms; 05.03.2013

Въпреки че не мога да напиша целия код вместо вас (сложен е), ето препоръчаната от мен настройка.

  1. Използвайте Tornado + Django: Tornado може да вгражда WSGI процеси, така че това ви дава възможността един процес да хоства както Django, така и този от манипулатора на Tornado. Ето кратка извадка от един от моите активни проекти (въпреки че това използва Tornado като манипулатор на Socket.io, трябва да ви даде същината на решението (:

    # Socket Server
    db = momoko.Pool(DB_DSN, **DB_CONFIG)
    router   = tornadio2.TornadioRouter(QueryRouter, user_settings={'db':db})
    sock_app = tornado.web.Application(router.urls, flash_policy_port = FL_PORT, flash_policy_file = path.join(PROJECT_ROOT, 'assets/xml/flashpolicy.xml'), socket_io_port = WS_PORT, debug=True)
    # Django Server
    os.environ['DJANGO_SETTINGS_MODULE'] = 'sever.settings'
    application = django.core.handlers.wsgi.WSGIHandler()
    container = tornado.wsgi.WSGIContainer(application)
    
    
    # Start the web servers
    if __name__ == "__main__":
        try:
            import logging
            tornado.options.parse_command_line()
            logging.getLogger().setLevel(logging.INFO)
            logging.info('Server started')
            tornado.locale.set_default_locale('us_US')
            http_server = tornado.httpserver.HTTPServer(container)
            http_server.listen(8000)
            tornadio2.SocketServer(sock_app, auto_start=True)
            tornado.ioloop.IOLoop.instance().start()
        except KeyboardInterrupt:
            tornado.ioloop.IOLoop.instance().stop()
            logging.info("Stopping servers.")
    

Това може лесно да се преобразува в два сървърни екземпляра, работещи на два различни порта, като 80 е запазено за Django, а 8080 се използва за вашия манипулатор на качване.

  1. Препоръчвам Tornado, защото поддържа тяло на заявка за поточно предаване и е много подходящо за този тип употреба. Ето същност, която може да ви помогне.

  2. Вашата прокси настройка ще има значение. Ако използвате NGINX, не забравяйте да изключите proxy_buffering.

  3. Не бих използвал база данни за проверка на тикет/качване. Redis или memcache вероятно биха били много по-бърз начин да се справите с това. Кешът също би бил чудесен начин за прогрес на качване на бас напред и назад между Django и Tornado, тъй като режийните разходи за настройка/получаване на нова стойност биха били толкова малки.

Това е голям космат проблем, който изисква сериозно инженерство, за да излезе с нещо елегантно, но е повече от осъществимо.

person Jack Shedd    schedule 27.02.2013
comment
Tornado включи ли тази кръпка на тялото на заявката за стрийминг? Изглежда, че кодът, споменат в Gist, всъщност използва разклонение на Tornado, което може да не бъде ангажирано обратно в основното репо. - person Naftuli Kay; 27.02.2013
comment
Не съм 100% сигурен. Може да се наложи да го разклоните и да приложите пластира върху вилицата. Не е голяма сделка. - person Jack Shedd; 27.02.2013
comment
да Как се обработва URL маршрутизирането? IE: Мога ли да маршрутизирам ^upload/anon/[a-zA-Z0-9]{32}$ към Tornado и всичко останало към Django безпроблемно? - person Naftuli Kay; 28.02.2013
comment
Хм. Възможно, но ще изисква малко повече работа. Ще трябва специално да предавате заявки за всеки URL адрес, за който сървърът на Tornado не се интересува от WGSI контейнера за Django. - person Jack Shedd; 01.03.2013