1

Я работаю над переносом существующего стандартного приложения среды GAE (Google App Engine) на гибкую среду. Я прочитал guide и решил попробовать python-compact runtime, так как всегда полезно повторно использовать как можно больше кода.Запуск фоновой темы в гибкой среде GAE с помощью Python-compact

В стандартном приложении окружения мы используем background_thread.start_new_background_thread(), чтобы создать пучок потоков бесконечного цикла, чтобы навсегда работать над некоторой фоновой работой. Однако я не мог заставить start_new_background_thread работать в гибкой среде, даже для некоторых действительно простых приложений. Как этот образец приложения: github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/background

Я получаю следующее error во время работы приложения в облаке (она отлично работает локально, хотя).

Я отлажена в нее, используя облако отладчик, но не было какое-либо сообщение об ошибке доступна на всех в то время как исключение был поднят в background_thread.py

Любая идея, как я могу работать в долгосрочной живой фоновый поток в гибкой среде с python-compact runtime? Благодаря!

ответ

1

Одна из отличий между стандартом App Engine и гибким интерфейсом App Engine заключается в том, что с помощью Flex мы действительно запускаем контейнер для докеров. Я могу придумать два подхода, чтобы попробовать.

1. Просто используйте Python многопроцессорной

стандарт App Engine обеспечивает соблюдение песочница, которые в основном означает, что нет прямого использования потоков или процессов. С Flex, вы должны иметь возможность просто использовать стандартный Python LIB для запуска нового процесса суб:

https://docs.python.org/3/library/subprocess.html

2. Использование supervisord и Докер

Если это не работает, то другой подход, который вы можете предпринять здесь, - это настроить изображение докеров, которое вы используете в Flex, и использовать superisord для запуска нескольких процессов. Во-первых, генерировать dockerfile по кд-ки в папку с источниками и работает:

gcloud preview app gen-config --custom

Это создаст Dockerfile, который можно настроить. Теперь вы захотите начать 2 процесса - процесс, который мы начали (я думаю, для python-compat это - gunicorn) и ваш фоновый процесс. Самый простой способ сделать это с грузчиком является использование supervisord:

https://docs.docker.com/engine/admin/using_supervisord/

После изменения вашего Dockerfile и добавления supervisord.conf, вы можете просто развернуть приложение, как обычно с gcloud preview app deploy.

Надеюсь, это поможет!

+0

Thanks @justin! Основная причина, по которой я хотел попробовать python-compact, - написать меньше кода для переноса существующего приложения GAE в новую среду. Я чувствовал, что все еще есть некоторый пробел для python-compact runtime. Поэтому я решил просто переписать его в стандартную среду исполнения python с gevent. Спасибо за идеи ура! – Sen

2

Желательно, чтобы в документации говорилось, что background_thread не поддерживает API.

Во всяком случае, я нашел несколько хаков, чтобы помочь с резьбовые несовместимости. В приложении Engine используется os.environ, чтобы прочитать множество настроек. «Реальные» потоки в вашем приложении будут иметь набор переменных среды, установленных там.Фоновые потоки, которые вы запускаете, не будут иметь. Один взломанный я использовал для копирования некоторых переменных окружения. Например, мне нужно было скопировать значение SERVER_SOFTWARE в потоки фона, чтобы получить доступ к библиотеке облачных хранилищ App Engine. Мы используем что-то вроде:

_global_server_software = None 
_SERVER_SOFTWARE = 'SERVER_SOFTWARE' 

def environ_wrapper(function, args): 
    if _global_server_software is not None: 
     os.environ[_SERVER_SOFTWARE] = _global_server_software 
    function(*args) 

def start_thread_with_app_engine_environ(function, *args): 
    # HACK: Required for the cloudstorage API on Flexible environment threads to work 
    # App Engine relies on a lot of environment variables to work correctly. New threads get none 
    # of those variables. loudstorage uses SERVER_SOFTWARE to determine if it is a test instance 
    global _global_server_software 
    if _global_server_software is None and os.environ.get(_SERVER_SOFTWARE) is not None: 
     _global_server_software = os.environ[_SERVER_SOFTWARE] 

    t = threading.Thread(target=environ_wrapper, args=(
     function, args)) 
    t.start()