Pull to refresh

Comments 7

Думал сейчас увижу как на PHP цифровые фильтры делают и БПФ используют. Ан нет.

У скриптов есть еще засада: бывает они зависают и приходится watch dog-и использовать.
Например если скрипт вызывать по расписанию, то в один прекрасный момент он может зависнуть даже при наличии set_time_limit. Раз в несколько месяцев обязательно. Так что приходится сигналить руками:
примерная реализация
class CheckProcess {
  var $pid_file="process.pid";
  var $time_limit=1860; // 31min
  function start($s) {
    if ($s) {
      file_put_contents($this->pid_file,getmypid());
    } else {
      if (file_exists($this->pid_file)) {
        $t1=filemtime($this->pid_file);
        $t2=time();
        $dt=$t2-$t1;
        if ($dt>$this->time_limit) {
          $pid=file_get_contents($this->pid_file);
          $pid=intval($pid,10);
          if ($pid) posix_kill($pid,SIGKILL);
          unlink($this->pid_file);
        }
      }
    }
  }
}
class FileMutex {
  var $fh;
  var $filename="process.mutex";
  var $locked=false;
  function __destruct() { $this->unlock(); }
  function lock() {
    $this->fh=fopen($this->filename,"w+");
    if (!$this->fh) throw new Exception("create file $this->filename");
    $this->locked=flock($this->fh,LOCK_EX|LOCK_NB);
    return $this->locked;
  }
  function unlock() {
    if ($this->locked) flock($this->fh,LOCK_UN);
    if ($this->fh) { fclose($this->fh); unset($this->fh); }
  }
}
set_time_limit(30*60); // 30min
$cp=new CheckProcess();
$fm=new FileMutex();
if ($fm->lock()) {
  $cp->start(true);
  do_smth();
} else {
  // busy
  $cp->start(false);
}
Жаль что пришлось вас огорчить, для этих целей наверное обходил бы php стороной :)
С зависанием сталкиватся не приходилось, я думаю причина может быть или в утечках или с алокацией памяти, этим могут болеть сторонние расширения.
Скрипты раньше работали на php 5.4 и кронах, сейчас на php 7.1 где-то supervisor где-то еще кроны.
Оффтоп, но я на это как-то кучу времени на эту ерунду потратил, может кому пригодится:
Есть ещё полезное применение сигналов и статусов завершения: таймаут для внешней команды. Вызывая внешнюю команду, вначале добавляем, например timeout 40 --kill-after=60 ..., после 40 секунд внешнему процессу будет передан sigterm, а если через 60 он всё ещё не закроется, то sigkill. Если ваша команда закрыта по таймауту, то вернётся статус 128, иначе статус, который она вернула. См man timeout.
Это единственный нормальный способ сбрасывать подвисшие команды из php, который я смог придумать, не считая всяких извращений. Спасло, когда в кликхаус-клиенте иногда навсегда зависали запросы, а его собственный таймаут не срабатывал.
Еще прикольнее когда команда нафоркала кучу исполнителей, а после её смерти они продолжают фтыривать.
Поправочка, не 128, а 124.
Подход, где один скрипт php отправляет другому php скрипту команду для обновления состояния будет действовать только в рамках одного сервера/виртуалки/контейнера. Но как быть, если два воркера должны общаться друг с другом, но они изолированы друг от друга, например, в разных docker?
Если я правильно понял вопрос – то для docker немного другой подход, то что в контейнере не должно обновляться.
Подымаем новый контейнер, а старый тушим (и туда идет сигнал чтобы получилось grasefull shutdown).
А если вам нужно реализовать прямое общение нескольких скриптов, в разных контейнерах, я бы смотрел на rest, jsonapi, socets.
Sign up to leave a comment.

Articles