Найти - Пользователи
Полная версия: как перенести GUI программу на сервер?
Начало » Python для новичков » как перенести GUI программу на сервер?
1
dimabest
На моем компьютере сутками работает GUI-программа (на Qt).

1. По таймеру (QTimer) запрашиваются (раз в несколько секунд) свежие данные с нескольких сайтов.
2. Все данные анализируются, а интересные данные отправляются на еще один сайт.
3. Все обращения в сеть идут через пул потоков. Это обязательно.

Хочу перенести на VPS, но опыта - ноль :)
Почитал про asyncore, twisted, python-daemon, signal, процессы-демоны и потоки-демоны… Теперь в голове полная каша :)

В примерах пишут как сделать сервер, который слушает порт, а мне нужен клиент.

Обязательные требования:
1. работа сутками без перезагрузок
2. start/stop из терминала
3. start с передачей параметров
4. stop c вызовом какой-нибудь функции для корректного завершения процесса
5. возможность реализовать пул потоков (для параллельной загрузки данных из сети)
o7412369815963
вырезать из кода Qt (сделать чисто консольным). и сделать авто-запуск через cron. если вручную стартовать, то можно через nohup.

если kill не подходит для завершения процесса, тогда можно делать stop-file который будет ждать скрипт, или xml-rpc управление сделать в скрипте.
o7412369815963
dimabest
Почитал про asyncore, twisted, python-daemon, signal, процессы-демоны и потоки-демоны…
это все необязательно, тем более что скрипт работает.
dimabest
cron отпадает из-за минимального интервала - 1 минута, а мне нужно вплоть до 1 сек.
dimabest
Играюсь с python-daemon, демон запускается без проблем. Как запустить таймер (threading.Timer) знаю, как сделать ThreadPool на очередях знаю. И там, и там ждем результат в бесконечных циклах, а как совместить 2 цикла? На горизонте маячат еще потоки и синхронизация…. :(
Alex2ndr
А какие конкретно трудности?
Имхо общая теория выглядит так:
1. Делаем демона. Можно сторонними разработками, а можно и самому написать через двойной fork. Имхо в 20 строк уложится можно. Примеров в инете много, теорию можно почитать у Стивенса.
2. Запускаем главный поток в котором устанавливаем таймер и запускаем пул потоков-обработчиков. Так же в этом потоке нужно подключить обработчик сигналов, чтобы ловить сигнал запуска и остановки. Почитать про это можно тут - http://docs.python.org/library/signal.html
3. Создаем очередь и по таймеру передаем туда задания. Каждый из потоков в пуле после обработки задания возвращает task_done.
4. После завершения всех очередей обрабатываем результаты, ждем конца таймера и запускаем все заново.
Вот статейка по очередям/потокам - http://keysolutions.ru/articles/osnovy-raboty-s-potokami-v-python

Но все конечно зависит от того как именно сделано у вас сейчас. Может быть там все проще. Плясать в любом случае надо от имеющихся материалов.
dimabest
У меня сложнее:

есть список объектов Query.

1. По таймеру запускается функция, которая отбирает Query со статусом WAITING, и проверяет - не пора ли загрузить свежие данные.
2. Объекты Query, для которых найдены свежие данные меняют статус на PROCESSING. Затем для каждого запрашиваются дополнительные данные. Причем пока эти данные будут подгружатся, может пройти секунды 4 и таймер запустится для свободных Query еще 4 раза.
Скорость очень важна, никто никого не ждет. Собственно говоря, скорость - главная причина переноса программы на VPS, ведь сайты в америке, а программа в Киеве.
3. Когда все загружено, данные нужно проанализировать и сложить инетересные на другой сайт.

Вобщем таймер живет своей жизню, а пул потоков своей.

Мне пришла интересная идея:
1. Делаю демона, который запускает QCoreApplication() (точнее уже сделал, работает!)
Пул потоков и таймер работают как в GUI программе, ничего менять не нужно.
2. Запускаю поток, в котором слушаю порт. Зачем? Через порт можно посылать команды! - перезагрузить конфиги, остановить демона (вызвав QCoreApplication.exit(0))
o7412369815963
dimabest
cron отпадает из-за минимального интервала - 1 минута, а мне нужно вплоть до 1 сек.
не, cron только для первичного запуска скрипта. а дальше он по таймеру будет крутиться, вместо QTimer.

у меня куча таких скриптов, уже более года стабильно работают.
и ещё есть скрипт-менеджер с web интерфейсом, через который можно стартовать/останавливать скрипты и смотреть логи…

+ скрипт мониторинг, который через web отражает статистику работы остальных скриптов - большая таблица с разноцветными полями: красный - ошибка, зеленый - все ОК и т.п.

вообщем полный набор :)
dimabest
Ха! Все получилось.

функция запуска приложения:
def main():
app = QCoreApplication(sys.argv)
d = MyDaemon()
d.run()
sys.exit(app.exec_())
Для запуска демона использую либу python-daemon:
context = daemon.DaemonContext(
stderr = open('/path/to/err.log', 'a+'),
# и другие параметры
# ......
)

with context:
main()
Класс MyDaemon наследую от QObject.
Для управления демоном создаю поток, в котором слушаю порт:
class Manager(QThread):
def __init__(self):
QThread.__init__(self)
self.srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.srv.bind((HOST, PORT))

def run(self):
while True:
self.srv.listen(1)
sock, addr = self.srv.accept()
cmd = sock.recv(64)
# и т.д.
Поток вещает сигналы с командами. Например, если cmd == ‘stop’, обработчик команды сохраняет данные, закрывает файлы, разрывает соединения и вызовом QCoreApplication.exit(0) завершает выполнение процесса-демона.

В утилите manage.py, собрал вместе функции start/stop/reconf, которые запускают демона, и создают сокеты с коннектом к демону и передачей команд.

Итого:
1. есть удобное управление демоном с корректным завершением
2. удобство работы с потоками, таймерами и сигналами от Qt
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB