Size: a a a

Natural Language Processing

2020 April 14

V

Vlad in Natural Language Processing
Да, Юра примерно так и написал)
источник

V

Vanya in Natural Language Processing
Yuri Baburov
ну вот надо теперь чтобы было несколько заранее созданных под клиентов, или чтобы они переиспользовались.
процессы заранее создаются под клиентов сейчас. У меня парсеры сейчас создаются во время обработки запроса. А я хочу заранее. При этом должна быть синхронизация между потоками
источник

V

Vlad in Natural Language Processing
А зачем синхронизация между потоками? Клиенты могут менять состояние парсеров?
источник

V

Vlad in Natural Language Processing
Мне кажется, будет логичнее каждому потоку/процессу присвоить свой экземпляр парсера
источник

V

Vanya in Natural Language Processing
менять состояние не могут, но разве работа функции findall атомарна для потока? Мне кажется, что нет
источник

V

Vlad in Natural Language Processing
Но в случае, если вы используете дочерние процессы, вы не сможете заранее проинициализировать в нём парсер и весь нужный код, а потом в нужный момент обратиться

В питоне вроде как нет такой возможности, вызыать метод какого-нибудь класса в дочернем процессе. Только создать процесс заново и там его сразу вызвать
источник

V

Vlad in Natural Language Processing
Под потоками вы понимаете потоки внутри процесса или пул дочерних процессов?
источник

V

Vanya in Natural Language Processing
потоки внутри процесса
источник

V

Vlad in Natural Language Processing
Про атомарность findall не могу сказать, не лез так глубоко)
Но в целом думаю будет проще/надёжнее взять что-то готовое для этого, типо gevent'а. Либо же, вообще забить на многопоточность, сделать однопоточный север, но запускать его через wsgi в многопоточном режиме. Там проблема атомарности должна быть решена, во всяком случае я с ней проблем ещё не ловил
источник

V

Vlad in Natural Language Processing
Т.е. мой совет заключается в решении проблемы не на уровне объектов ваших парсеров, а на уровне сервера целиком. Это, как мне кажется, проще и меньше головной боли
источник

V

Vlad in Natural Language Processing
Хотя это немного и не выгодно по оперативной памяти, но сейчас она стоит копейки, не думаю, что это будет проблема
источник

A

Ahlesen in Natural Language Processing
источник

V

Vlad in Natural Language Processing
В случае flask+gevent вы просто для запуска сервера используете gevent.wsgiserver (или как-то так, не помню точное название), и передаёте ему объект приложения Flask

По умолчанию, gevent wsgi server будет использовать главный пул гринлетов в родительском процессе, тем самым он нагрузит ваше ядро, на котором живёт сервер, по максимуму

При этом вы не запариваетесь про доступ к экземплярам парсеров и других ваших объектов, это решается но более высоком уровне средствами gevent (а точнее того, как он работает с гринлетами - формально, с "потоками")

А после запускаете несколько серверов и балансируете между ними нагрузку

Если вы не хотите заниматься балансировкой нагрузки, можно попробовать при создании gevent wsgi server передать ему пул listener'ов и в итоге получите пул подсерверов, которые будут слушать один порт и сами делить друг с другом запросы
источник

V

Vlad in Natural Language Processing
Вот тут примерная схема с процессами описана: https://stackoverflow.com/questions/7407868/gevent-pywsgi-server-multiprocessing

Я пока не добрался до того, что б её проверить и отказаться от балансировщика на nginx и пула докер контейнеров
источник

I

Ilya in Natural Language Processing
Можно с помощью https://docs.python.org/3/library/concurrent.futures.html создать пул воркеров и через initializer на воркерах создать объект-парсер
источник

V

Vlad in Natural Language Processing
Vlad
Вот тут примерная схема с процессами описана: https://stackoverflow.com/questions/7407868/gevent-pywsgi-server-multiprocessing

Я пока не добрался до того, что б её проверить и отказаться от балансировщика на nginx и пула докер контейнеров
В примере по ссылке, при создании pywsgi.WSGIServer() передайте ему application=Flask(), который или в этот же момент, или заранее проинициализировали, это не важно

т.е. типо так:
app = Flask(name)
...
http_server = WSGIServer(listener, application=app, ...)
http_server.serve_forever()  # с этого момента сервер запущен

В случае многопроцессности примерно так же, только для каждого вашего процесса отдельно, как в примере по ссылке
источник

V

Vanya in Natural Language Processing
Ilya
Можно с помощью https://docs.python.org/3/library/concurrent.futures.html создать пул воркеров и через initializer на воркерах создать объект-парсер
Можно и так. Но у меня gunicorn создаёт воркеров. Если парсеры прописаны в глобальной области, то они будут созданы только во время запуска гуникорна. Но тогда возникает проблема, если воркер многопоточный
источник

V

Vanya in Natural Language Processing
Vlad
В примере по ссылке, при создании pywsgi.WSGIServer() передайте ему application=Flask(), который или в этот же момент, или заранее проинициализировали, это не важно

т.е. типо так:
app = Flask(name)
...
http_server = WSGIServer(listener, application=app, ...)
http_server.serve_forever()  # с этого момента сервер запущен

В случае многопроцессности примерно так же, только для каждого вашего процесса отдельно, как в примере по ссылке
Я использую гуникорн в качестве сервера, там можно указать, чтобы процессы использовали gevent
источник

V

Vlad in Natural Language Processing
Возможно, будет тот же эффект, если использовать только gevent. Стоит попробовать тесты погонять, что б оценить
источник

AZ

Alexandr Zamaraev in Natural Language Processing
Для каждого воркера/потока создаёшь экземпляр на старте. Потом его используешь при обработке запроса.
источник