Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 28, 2010 05:41:21

dimabest
От:
Зарегистрирован: 2009-02-12
Сообщения: 253
Репутация: +  0  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

На моем компьютере сутками работает GUI-программа (на Qt).

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

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

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

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



Офлайн

#2 Дек. 28, 2010 06:23:44

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

вырезать из кода Qt (сделать чисто консольным). и сделать авто-запуск через cron. если вручную стартовать, то можно через nohup.

если kill не подходит для завершения процесса, тогда можно делать stop-file который будет ждать скрипт, или xml-rpc управление сделать в скрипте.

Офлайн

#3 Дек. 28, 2010 06:26:16

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

dimabest
Почитал про asyncore, twisted, python-daemon, signal, процессы-демоны и потоки-демоны…
это все необязательно, тем более что скрипт работает.

Офлайн

#4 Дек. 28, 2010 06:54:02

dimabest
От:
Зарегистрирован: 2009-02-12
Сообщения: 253
Репутация: +  0  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

cron отпадает из-за минимального интервала - 1 минута, а мне нужно вплоть до 1 сек.



Офлайн

#5 Дек. 28, 2010 07:08:25

dimabest
От:
Зарегистрирован: 2009-02-12
Сообщения: 253
Репутация: +  0  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

Играюсь с python-daemon, демон запускается без проблем. Как запустить таймер (threading.Timer) знаю, как сделать ThreadPool на очередях знаю. И там, и там ждем результат в бесконечных циклах, а как совместить 2 цикла? На горизонте маячат еще потоки и синхронизация…. :(



Офлайн

#6 Дек. 28, 2010 13:30:35

Alex2ndr
От:
Зарегистрирован: 2009-12-26
Сообщения: 204
Репутация: +  0  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

А какие конкретно трудности?
Имхо общая теория выглядит так:
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

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



Офлайн

#7 Дек. 28, 2010 16:12:32

dimabest
От:
Зарегистрирован: 2009-02-12
Сообщения: 253
Репутация: +  0  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

У меня сложнее:

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

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

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

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



Офлайн

#8 Дек. 28, 2010 18:53:17

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

dimabest
cron отпадает из-за минимального интервала - 1 минута, а мне нужно вплоть до 1 сек.
не, cron только для первичного запуска скрипта. а дальше он по таймеру будет крутиться, вместо QTimer.

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

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

вообщем полный набор :)

Отредактировано (Дек. 28, 2010 18:57:12)

Офлайн

#9 Дек. 29, 2010 01:33:39

dimabest
От:
Зарегистрирован: 2009-02-12
Сообщения: 253
Репутация: +  0  -
Профиль   Отправить e-mail  

как перенести GUI программу на сервер?

Ха! Все получилось.

функция запуска приложения:

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



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version