Форум сайта python.su
Возникла задача, в которой есть сотня-другая очень малонагруженных приложений-сервисов,
которые общаются друг с другом и с приложениями на других серверах посредством, например, ZeroMQ (непринципиально).
Запускать столько приложений отдельно одновременно, боюсь никакого ОЗУ не хватит.
Обязательно нужно иметь возможность любое приложение останавливать, модифицировать код и снова запускать.
Привожу рисунок для лучшего понимания задачи. Что посоветуете?
Отредактировано alexte (Окт. 20, 2015 21:09:19)
Прикреплённый файлы: Концепция.png (13,7 KБ)
Офлайн
alexteНапример в ZMQ сообщения могут вставать в очередь на обработку, обработчики при этом не обязаны быть в оперативной памяти. Диспетчер обработчиков может их подгружать после посылки им сообщений.
ZeroMQ (непринципиально).
Отредактировано doza_and (Окт. 20, 2015 21:53:58)
Офлайн
Если приложение жрёт 100мб, например. И их сотня-другя. То это 10-20гб. В чём проблема?
Офлайн
Проблема в том, что ОЗУ ограничено и сильно. Это миникомпьютеры на ARM всего с 1ГБ.
В принципе задача почти решена при помощи asyncio task. Разбираюсь с возможностью перезагрузки модулей “на лету”…
Офлайн
Решил. Что-то нарыл в инете, что-то дописал.
Вот основной модуль
import time import asyncio import functools from threading import Thread, current_thread, Event from concurrent.futures import Future import importlib import sys class Apps(Thread): def __init__(self, start_event): Thread.__init__(self) self.loop = None self.tid = None self.event = start_event def run(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.tid = current_thread() self.loop.call_soon(self.event.set) self.loop.run_forever() def stop(self): self.loop.call_soon_threadsafe(self.loop.stop) def add_task(self, coro): """this method should return a task object, that I can cancel, not a handle""" def _async_add(func, fut): try: ret = func() fut.set_result(ret) except Exception as e: fut.set_exception(e) f = functools.partial(asyncio.async, coro, loop=self.loop) if current_thread() == self.tid: return f() # We can call directly if we're not going between threads. else: # We're in a non-event loop thread so we use a Future # to get the task from the event loop thread once # it's ready. fut = Future() self.loop.call_soon_threadsafe(_async_add, f, fut) return fut.result() def cancel_task(self, task): self.loop.call_soon_threadsafe(task.cancel) class Tasks: def __init__(self, module): self.module = module importlib.import_module(self.module) self.t = appl.add_task(sys.modules[self.module].tst1()) def reload(self): appl.cancel_task(self.t) importlib.reload(sys.modules[self.module]) self.t = appl.add_task(sys.modules[self.module].tst1()) def cancel(self): appl.cancel_task(self.t) event = Event() appl = Apps(event) appl.start() event.wait() # Let the loop's thread signal us, rather than sleeping t1 = Tasks('appl1') t2 = Tasks('appl2') t3 = Tasks('appl3') time.sleep(5) t1.reload() t2.reload() time.sleep(5) t1.cancel() t2.cancel() t3.cancel() time.sleep(1) appl.stop()
import asyncio @asyncio.coroutine def tst1(): i = 0 while True: print('appl1... {0}'.format(i)) i += 1 yield from asyncio.sleep(1)
Отредактировано alexte (Окт. 26, 2015 10:58:50)
Офлайн
alexteМожет тупо по типу CGI: одно приложение, которое слушает очередь, запускает другие, передавая им параметры из очереди и собирая их выхлоп?
Возникла задача, в которой есть сотня-другая очень малонагруженных приложений-сервисов,которые общаются друг с другом и с приложениями на других серверах посредством, например, ZeroMQ
Офлайн
alexte
расскажите что за конкретно микропк, название/модель ?
Офлайн
t1 = Tasks('appl1') t2 = Tasks('appl2') t3 = Tasks('appl3') time.sleep(5) t1.reload() t2.reload() time.sleep(5) t1.cancel() t2.cancel() t3.cancel() time.sleep(1) appl.stop()
yield from asyncio.sleep(1)
Офлайн
Код, приведенный ниже классов, - это просто маленький тест на создание приложений их перезагрузку и остановку. Если запустите, то увидите зачем там паузы.
JOHN_16
расскажите что за конкретно микропк, название/модель ?
Офлайн
Офлайн