LINUX.ORG.RU

Flask Theread Context Variable


1

1

как во фласке сделать общедоступную переменную,
чтобы инициализировать переменну в потоке в одном модуле, а в других обращаться к ней, без повторной инициализации?

★★★

Можно юзкейс? не совсем понятно что именно нужно сделать

C1nde
()
Ответ на: комментарий от Kesha_Molchanov

нормальное решение, но похоже у меня проблема в том, что Flask запускат n-e количество потоков с моими приложениями, и каждое приложение создаёт свою переменную и в рамках своего потока, ну и каждый при каждый раз выполняется однотипная длительная инициализация

какие ещё могут решения кроме вынесения этого в отдельный процесс и подключения к нему через какие нить каналы?

fMad ★★★
() автор топика
Ответ на: комментарий от fMad

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

Kesha_Molchanov
()
Ответ на: комментарий от Kesha_Molchanov

Flask ведь потоки запускает и как то по своему.
потому что я объявил список своих объектов глобально, твоим способом, он после запуска начинает инициализировать эти объекты, но после запуска wsgi запускаются несколько потоков инициализирующий это список объектов

fMad ★★★
() автор топика

К тому же у тебя заголовок темы не соответствует посту, ты точно понимаешь что хочешь?

bj
()
Ответ на: комментарий от bj

в смысле как?


import get_task_list

def Init_Task_List(sleep=3):
    print "Init_Task_List", os.getpid()
    lock = threading.Lock()
    lock.acquire()
    time.sleep(sleep)
    for i, vk in enumerate(get_task_list()):
        try:
            ... 
        except:
            ...

t = threading.Thread(target=Init_Task_List, args=())
t.daemon = True
t.start()

ну а затем

[uwsgi]
socket = /tmp/proj1.sock
master = true
enable-threads = true
processes = 3 
chdir = proj1/
module = app:app
virtualenv = env/
fMad ★★★
() автор топика
Ответ на: комментарий от bj

во фласке есть глобальная переменная g, но её как то хитро нужно использовать в контексте множества запросов
об этом и спрашиваю

fMad ★★★
() автор топика
Ответ на: комментарий от fMad
lock = threading.Lock()
lock.acquire()

Этот лок ничего не лочит. Потому что создается в каждом потоке. Видимо проблема в этом.

во фласке есть глобальная переменная g, но её как то хитро нужно использовать в контексте множества запросов

Нет никакой хитрости, если на пальцах, то для каждого реквеста g своя и для «чтобы инициализировать переменну в потоке в одном модуле, а в других обращаться к ней, без повторной инициализации» она не подходит вообще.

bj
()
Ответ на: комментарий от bj

это я уже понял, вот и ищу решение попроще чем отдельный сервер.

это лок нужен чтобы заблокировать если в текущем потоке его снова кто-то попытается запустить

fMad ★★★
() автор топика
Последнее исправление: fMad (всего исправлений: 1)
Ответ на: комментарий от fMad

это лок нужен чтобы заблокировать если в текущем потоке его снова кто-то попытается запустить

Запустить target? Иначе он не сработает. У тебя какая-то каша. Задачу (в оппосте не задача, а проблема с который ты столкнулся попытавшись криво решить задачу) можешь описать?

bj
()
Ответ на: комментарий от bj

в общем у меня есть список различных роботов, которые выполняют различные спланированные задания
на запуск (создание новых сессий, иницилизация объектов через сеть из файлов) всего списка тратится много времени, а со временем это будет весьма недопустимо большое время

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

в итоге хочу получить список запущенны роботов, обрабатывающих задания с Flask интефейсом

fMad ★★★
() автор топика
Последнее исправление: fMad (всего исправлений: 1)

нифига не понял, но может тебе поможет @app.before_request(*args, **kwargs) ?

ggrn ★★★★★
()
Ответ на: комментарий от fMad

Вот иллюстрация твоего лока, неработающего:

from time import sleep
from threading import Thread, Lock


def do_something(msg):
    with Lock():
        print msg
        sleep(10)


def make_thread(msg):
    Thread(target=do_something, args=(msg,)).start()


make_thread('I must be locked!')
make_thread('What?')
make_thread('WTF!!!!')
bj
()
Ответ на: комментарий от fMad

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

сначала инициализацию запускай. Потом стартуй свои потоки. Все равно потоки без данных работать не смогут.

Kesha_Molchanov
()
Ответ на: комментарий от fMad

в итоге хочу получить список запущенны роботов, обрабатывающих задания с Flask интефейсом

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

мешать в одну кучу http и роботов я бы не стал.

Kesha_Molchanov
()
Ответ на: комментарий от fMad

подключения к нему через какие нить каналы?

для этого самое простое redis. В принципе можно чем угодно, хоть писать состояние роботов в файл, а фласком его читать и проказывать в браузер.

Kesha_Molchanov
()
Ответ на: комментарий от bj

потому что не слышал про Celery

fMad ★★★
() автор топика
Ответ на: комментарий от x3al

и
[code]
print «Init_Task_List», os.getpid()
[/code]

мне об этом говорил.
Но ведь Flask каким то образом помнит сессию, а не заставляет логинится 3 раза

fMad ★★★
() автор топика
Ответ на: комментарий от fMad

Ты уверен, что её помнит не браузер? Типикал-реализация сессий — куки, которые шлёт браузер, в них вполне может быть всё необходимое состояние.

x3al ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.