LINUX.ORG.RU
ФорумAdmin

Перезапуск программы при восстановлении связи с сервером.

 ,


0

1

Доброго всем времени, дорогие форумчане). Прошу вашей помощи. Появилась небольшая проблема (а может и большая). Пытался самостоятельно решить ее, но так как в линуксе недавно, замучил гуголь досмерти)), а подходящего решения так и не нашел((.

Вообщем суть проблемы такова: есть приложение, которое зависает при потери связи с сервером. После восстановления связи софтина так и продолжает висеть. И сервер и клиент (где висит софтина) в одной локальной сети. Не могу сообразить как написать скрипт, но смысл его примерно такой:

1. Скрипт всегда работает (на клиенте) и проверяет связь с сервером. Если связь есть - ничего не делает.

2. Связь с сервером пропала - тоже ничего не делает, ждет когда появится.

3. Связь появилась - killall <висящая прога> && <запуск проги>.

4. Скрипт продолжает вести наблюдение))

На всякий случай: ОС Debian 8.6, на обоих машинах. Очень надеюсь на вашу помощь.


Что есть связь с сервером? Например завис как проверять будем? Предположим что это субд, тестируем просто подключение к ней. Но есть нюанс, может быть, что в промежуток между тестовыми подключениями сервак переподнялся. А клиент-то уже висит.
Вообще сферически проблема по большому счету в клиенте.

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

Потеря связи - это перезапуск сервера, либо кто то отключил патчкорд, либо он завис и ждет когда его перезапустят (это к примеру). Проверить его доступность можно пингом.

То есть:

-пингуем ip-шник -c 5 - ответ есть - все хорошо.

-ждем 15 секунд

-пингуем ip-шник -c 5 - ответ есть - все хорошо.

-ждем 15 секунд

-пингуем ip-шник -c 5 - ответа нет - все плохо, ничего не делаем.

-ждем 15 секунд

-пингуем ip-шник -c 5 - ответ есть - убиваем процесс и запускаем прогу.

-ждем 15 секунд

-пингуем ip-шник -c 5 - ответ есть - все хорошо. И т.д.

Если так сделать нельзя, то процесс убить можно сразу после потери связи и запустить после ее восстановления.

Я понимаю, что проблема в клиенте, но сейчас ее решить невозможно. Решение проблемы скриптом - это временное решение.

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

Если есть систумд - сделай микросервис, который будет пинговать раз в 5 секунд удаленный хост и вываливаться с ошибкой если пинг пропал. Далее влепи его как зависимость для основного демона и поставь авторестарт с задержкой 5 секунд. Можно еще с notify пошаманить чтоб он сообщал что он running только после первого пинга

Можно и без систумд, но там это прозрачнее, хоть и куда менее гибко

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

Ок. И да - сорри, почему-то подумал что прога это демон.

Пара наводящих вопросов: как запускается прога (./ или ярлык или service или systemctl)? У проги есть гуй (если да - какой DE)? Юзает ли ее кто-то еще (условная секретарша)? Можно ли тупо пускать ее на сервере и юзать свой комп как тонкий клиент?

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

Нет, прога не демон. Имеет гуй, DE KDE. Есть еще один ньюанс. Софтина работает в wine. Рабочих мест (машин где стоит прога) на данный момент 2. На сервере прога тоже всегда запущена (можно сказать третье рабочее место). Как тонкий клиент использовать нельзя.

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

ок. ща я буду пытаться увернуться от тухлых помидоров поскольку мое bash-фу средней паршивости

#!/bin/bash

SERVER_IP=8.8.8.8
TIMEOUT=5
MYPROG=/usr/bin/pcmanfm

function restart {
  if [ -f ~/program_current.pid ]; then
    kill -9 $(cat ~/program_current.pid)
  fi
  exec $MYPROG &
  echo $! > ~/program_current.pid
}

INTR=
trap 'INTR=yes; echo "** INTR **" >&2' INT

while true
do
    (
        # Protect the subshell block
        trap '' INT

        # Ping
        ping -q -c 2 -i $TIMEOUT -w $( expr $TIMEOUT \* 2 ) $SERVER_IP &> /dev/null
        if [ $? -eq 0 ]; then 
          echo "Server is alive"
          if [ ! -f ~/program_current.pid ]; then 
            echo "Restarting..."
            restart
          fi 
        else 
          echo "Server is down"
          rm -f ~/program_current.pid
        fi
    )
    SS=$?

    echo "RUNNING = $RUNNING"

    # Ctrl/C, perhaps?
    test yes = "$INTR" && echo "Matched INTR" >&2 && break
done
rm -f ~/program_current.pid
exit 0

Как понятно по коду - используется файл ~/program_current.pid, который собственно хранит PID твоей проги, и по этому PID она и убиваетя. почему спрашивал про гуй - у меня кед нету, но вместо некрасивого echo "Server is down" можно заюзать kdialog (с if по тому же файлу прямо перед его удалением) с предупреждением что труба рулю и можно идти курить.

единственный хз на счет вайна - не уверен что он так вот легко в связке pid+kill отработает, но тогда уж можно и правда killall

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

ок. ща я буду пытаться увернуться от тухлых помидоров поскольку мое bash-фу средней паршивости

У вас не сколько с bash-ем проблемы, сколько логика странная. После «Server is down» удаляете pid-файл. Как же потом килять то при alive?

Ну и да, давненько я такого не видал: «$( expr $TIMEOUT \* 2 )», лет 20 наверное. Сейчас трудно найти shell, где не поддерживается синтаксис «$(($TIMEOUT*2))», а для bash-а так и вовсе $ у $TIMEOUT не нужен. Скобки внутри do-done тут не нужны. SS - какая-то отладочная переменная?

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

У вас не сколько с bash-ем проблемы, сколько логика странная. После «Server is down» удаляете pid-файл. Как же потом килять то при alive?

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

SS - какая-то отладочная переменная

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

Скобки внутри do-done тут не нужны

см выше, но разве тогда не придется sigint два раза слать, на пинг и на while?

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

Сейчас не на работе, проверил дома на буке. Вообщем вот что получилось:

1. Проверил на chromium-е и на dolphin, после восстановления связи (для эксперимента тупо отключал вифи), запускается новый экземпляр приложения, но старый не убивается.

2. Приложение в wine (подопытным был qip): процесс не убивается и не запускается((

Есть какие мысли на счет этого?

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

я хз как в цикле между итерациями нормально передать булевую переменную чтоб она сохранялась.

Не понимаю проблему... Уберите вообще сопроцесс () и устанавливайте сколько угодно переменных. while - это оператор цикла, а не внешняя программа с отдельными переменными.

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

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

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