B
B
Boris Lapin2015-02-01 20:01:43
Python
Boris Lapin, 2015-02-01 20:01:43

How to run in a separate thread an eternal loop to iterate through some variable in Tornado?

The task is this. It is necessary to implement a function that will iterate over some public list and destroy itself (along with the stream), in case this list suddenly becomes empty. Then, when adding a new element to this list, you need to somehow call this function, which does the same thing.
The function, I call the cleaner
An example of a piece of code of how I did it:
(I omitted importing modules and other details to show only the essence)

# Обработчик WebSocket соединений
class WSHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        pass
    def on_close(self):
        # Узнаем остановлен ли чистильщик
        startCleaner = False
        if len(app.SessionsRestore) < 1:
            startCleaner = True
        
        # Временно сохраняем сессию в хранилище
        app.SessionsRestore.append({
            "sid":self.sid,
            "time_of_dead":datetime.now() + timedelta(minutes=5),
            })
        
        # Запускаем чистильщик сессий, если он был остановлен
        if startCleaner:
            app.clear_sessions_restore()
    
    def on_message(self,data):
        #Тут делаем разнообразные операции, не зависимо от чистильщика и т.п.
        pass

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/ws", WSHandler),
        ]
        # Это список, который должен перебирать чистильщик
        self.SessionsRestore = list()
        
        tornado.web.Application.__init__(self, handlers)

    # Чистильщик, работающий асинхронно
    # Следит за тем, чтобы сессии не лежали в этом хранилище слишком долго
    @tornado.web.asynchronous
    def clear_sessions_restore(self):
        while True:
            # Останавливаем чистильщик, если чистить нечего
            if len(self.SessionsRestore) < 1:
                break
            # Уменьшаем количество проходов в секунду
            time.sleep(5)
            # Осуществляем проход по хранилищу сессий
            for session in self.SessionsRestore:
                if session['time_of_dead'] > datetime.now():
                    self.SessionsRestore.remove(session)

# И примерно такой запуск серва
if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = Application()
    app.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

So, I thought that using the @tornado.web.asynchronous decorator would make the method asynchronous, but that was not the case. On the line where this method is called, code execution hangs until the "eternal" loop inside this method ends. In this regard, I don’t see anything but how to write everything by hand, using the threading module, etc. It's not difficult to do this, but I would like to do it with tornado resources. And don't use bikes.
I'm developing from Windows. Maybe because of this, all the problems and on * nix everything will be okay? If so, then tell me how you can implement normal asynchrony support, albeit unproductive, but without picking the code of the project itself.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Andrey K, 2015-02-01
@MrBoriska

Tornado won't help. It is necessary to separate the function into a separate process.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question