Периодическая выборка данных должна блокировать другие потоки, используя планировщик
Я новичок в питоне. Я благодарен за любую помощь. Итак, начнем.
Я использую приложение FLASK как API для отдыха. С каждым запросом возвращается JSON. Там может быть около 20 запросов в секунду. В фоновом режиме я использую APscheduler для получения фактических данных каждые 60 секунд из ldap.
scheduler = BackgroundScheduler()
scheduler.add_job(
func=my_ldap.fetch_people_ldap,
trigger=IntervalTrigger(seconds=60),
id='fetching_data_job',
name='Fetch data from ldap every 60 seconds')
scheduler.start()
atexit.register(lambda : scheduler.shutdown())
Но на самом деле, когда происходит обращение к datafetch с помощью вызова API, приложение закрывается из-за проблемы с памятью, я думаю, что это является причиной того, что я получаю доступ к объекту ldap одновременно fetch_people_ldap
- функция вызывается планировщиком.
Я хочу решить эту ужасную ошибку, заблокировав поток, который обрабатывает вызовы API, до успешного завершения извлечения данных ldap. Но я не знаю, как это сделать.
Есть ли какие-либо рекомендации или решения?
Это журнал, который я получаю за ошибку: Фатальная ошибка Python: сохранение потока дважды?
Thread 0x00007f95f3fff700 (most recent call first):
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 294 in _ldap_call
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 721 in result4
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 714 in result3
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 707 in result2
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 703 in result
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 796 in search_ext_s
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 802 in search_s
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/ldap_check/ldapCheck.py", line 49 in fetch_people_ldap
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/apscheduler/executors/base.py", line 125 in run_job
File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55 in run
File "/usr/lib/python3.5/concurrent/futures/thread.py", line 66 in _worker
File "/usr/lib/python3.5/threading.py", line 862 in run
File "/usr/lib/python3.5/threading.py", line 914 in _bootstrap_inner
File "/usr/lib/python3.5/threading.py", line 882 in _bootstrap
Thread 0x00007f95f8910700 (most recent call first):
File "/usr/lib/python3.5/threading.py", line 297 in wait
File "/usr/lib/python3.5/threading.py", line 549 in wait
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/apscheduler/schedulers/blocking.py", line 28 in _main_loop
File "/usr/lib/python3.5/threading.py", line 862 in run
File "/usr/lib/python3.5/threading.py", line 914 in _bootstrap_inner
File "/usr/lib/python3.5/threading.py", line 882 in _bootstrap
Current thread 0x00007f9605505700 (most recent call first):
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 294 in _ldap_call
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 791 in search_ext
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 795 in search_ext_s
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 802 in search_s
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/ldap_check/ldapCheck.py", line 59 in check_node
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/ldap_check/ldapCheck.py", line 118 in build_tree_recursive
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/ldap_check/ldapCheck.py", line 124 in build_tree_recursive
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/ldap_check/ldapCheck.py", line 124 in build_tree_recursive
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/ldap_check/ldapCheck.py", line 129 in build_tree
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/app/app.py", line 83 in get_trainings_by_unit
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/flask/app.py", line 1598 in dispatch_request
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/flask/app.py", line 1612 in full_dispatch_request
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/flask/app.py", line 1982 in wsgi_app
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/flask/app.py", line 1997 in __call__
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/werkzeug/serving.py", line 197 in execute
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/werkzeug/serving.py", line 209 in run_wsgi
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/werkzeug/serving.py", line 267 in handle_one_request
File "/usr/lib/python3.5/http/server.py", line 422 in handle
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/werkzeug/serving.py", line 232 in handle
File "/usr/lib/python3.5/socketserver.py", line 681 in __init__
File "/usr/lib/python3.5/socketserver.py", line 354 in finish_request
File "/usr/lib/python3.5/socketserver.py", line 341 in process_request
File "/usr/lib/python3.5/socketserver.py", line 313 in _handle_request_noblock
File "/usr/lib/python3.5/socketserver.py", line 234 in serve_forever
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/werkzeug/serving.py", line 539 in serve_forever
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/werkzeug/serving.py", line 702 in inner
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/werkzeug/serving.py", line 739 in run_simple
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/flask/app.py", line 841 in run
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/app/app.py", line 92 in <module>
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
1 ответ
Проблема в том, что ваш обработчик вызовов API также вызывает LDAP для создания ответа. Если вы будете получать 20 запросов в секунду, это вызовет проблемы. Запланированный звонок также не имеет особого смысла, потому что, когда вы используете полученные данные?
Мой подход заключается в том, чтобы запланированное задание обновляло общее хранилище данных в фоновом режиме. Тогда ваш вызов API только читает данные из этого общего хранилища данных и вообще не должен касаться LDAP. Используете ли вы базу данных или просто память, зависит от размера и сложности данных, с которыми вы работаете.
Главное состоит в том, чтобы отделить создание ответа API от извлечения данных из LDAP.
РЕДАКТИРОВАТЬ: я понимаю из вашего комментария, что вы думаете, что ваш API использует только ваш собственный код ldapCheck.py, но если вы посмотрите на трассировку полного стека, он на самом деле использует библиотеку LDAP для вызова:
API Thread:
Current thread 0x00007f9605505700 (most recent call first):
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 294 in _ldap_call
...
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/ldap_check/ldapCheck.py", line 124 in build_tree_recursive
...
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/app/app.py", line 83 in get_trainings_by_unit
...
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/flask/app.py", line 841 in run
Когда это происходит одновременно с тем, как ваш запланированный фоновый поток выполняет вызов LDAP, вы получаете эту ошибку.
Thread 0x00007f95f3fff700 (most recent call first):
File "/path/to/folder/virtual_env_1/lib/python3.5/site-packages/pyldap-2.4.37-py3.5-linux-x86_64.egg/ldap/ldapobject.py", line 294 in _ldap_call
...
File "/path/to/folder/tt_report_api/training_tool_report_api/sample/ldap_check/ldapCheck.py", line 49 in fetch_people_ldap
...
File "/usr/lib/python3.5/threading.py", line 882 in _bootstrap
Решение не состоит в том, чтобы заблокировать Ваш поток API. Решение состоит в том, чтобы убедиться, что код в ldapCheck.py", line 59 in check_node
не обращается к вашей библиотеке LDAP, но использует информацию, уже извлеченную и сохраненную фоновым потоком.