Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Where to catch Premature worker death and processed it #25

Closed
mikuho opened this issue Mar 15, 2020 · 3 comments
Closed

Where to catch Premature worker death and processed it #25

mikuho opened this issue Mar 15, 2020 · 3 comments

Comments

@mikuho
Copy link

mikuho commented Mar 15, 2020

Hello, if there is an exception:

2020-02-26 04:02:06.0448: 6526 6526: DEBUG: Mediator [example]: Premature worker death was reaped [PID=6527] [Call=2] [Status=CALLED]

I would like to do a few cleaning operations related to that worker. Can you give me some advice where to catch it and do some operations? Or how?

I would be grateful for a little an example because I am new to Promise pattern.

Here is my my daemon:

<?php
require __DIR__ . '/vendor/autoload.php';

use Lifo\Daemon\Daemon;
use Lifo\Daemon\Mediator\Mediator;

use Lifo\Daemon\LogTrait;
use Lifo\Daemon\Promise;

class MyWorker {
  public function getUrl($endPoint) {
    sleep(1); // fake latency

    // To do something...

    // When finished it return url api
    return $endPoint;
  }
}

class MyDaemon extends Daemon {
  public $api = array('www.api1.com', 'www.api2.com', 'www.api3.com', 'www.api4.com', 'www.api5.com', 'www.api6.com');
  public static $runningApi = array();

  public function getApi() {
    static $loop = 1;
    $counter = sizeof($this->api);
    if ($counter >= $loop) {
      $api = $this->api[$loop-1];
    } else {
      $loop = 1;
      $api = $this->api[$loop-1];
    }
    $loop++;
    return $api;
  }

  public function initialize() {
    $this->addWorker(new MyWorker(), 'example')->setAutoRestart(true)->setMaxProcesses(6);
  }

  public function execute() {
      $api = $this->getApi();
      $key = array_search($api, self::$runningApi);
      if ($key === false) {
        self::$runningApi[] = $api;
        // the worker method will return a Promise
        $this->worker('example')->getUrl($api)->then(function($url) {
          $this->log("URL API received: %s", $url);
          $key = array_search($url, self::$runningApi);
          if ($key !== false) {
            unset(self::$runningApi[$key]);
          }
        });
      }
  }
}

MyDaemon::getInstance()->setVerbose(true)->setDebug(true)->setLogFile('/tmp/MyDaemon.log')->run();

Thank you

@lifo101
Copy link
Owner

lifo101 commented Mar 16, 2020

Take a look at the example in the docs: https://github.com/lifo101/php-daemon/wiki/Workers#return-value

@mikuho
Copy link
Author

mikuho commented May 1, 2020

Hello, I updated my daemon to this...I would like get a PID of the $worker = $this->worker('example'), but I dont know how ($worker->call->getPid())

<?php
require __DIR__ . '/vendor/autoload.php';

use Lifo\Daemon\Daemon;
use Lifo\Daemon\Mediator\Mediator;

use Lifo\Daemon\LogTrait;
use Lifo\Daemon\Promise;

class MyWorker {
  public function getUrl($endPoint) {
    sleep(1); // fake latency

    // To do something...

    // When finished it return url api
    return $endPoint;
  }
}

class MyDaemon extends Daemon {
  public $api = array('www.api1.com', 'www.api2.com', 'www.api3.com', 'www.api4.com', 'www.api5.com', 'www.api6.com');
  public static $runningApi = array();

  public function getApi() {
    static $loop = 1;
    $counter = sizeof($this->api);
    if ($counter >= $loop) {
      $api = $this->api[$loop-1];
    } else {
      $loop = 1;
      $api = $this->api[$loop-1];
    }
    $loop++;
    return $api;
  }

  public function initialize() {
    $this->addWorker(new MyWorker(), 'example')->setAutoRestart(true)->setMaxProcesses(6);
  }

  public function execute() {
      $api = $this->getApi();
      if (!in_array($api, self::$runningApi)) {
        // Here I would like get PID
        $worker = $this->worker('example');
        $pid = // How can get PID of this worker... something like $worker->call->getPid()?
        self::$runningApi[$pid] = $api;

        // the worker method will return a Promise
        $worker->getUrl($api)->then(function($data) {
            //$call = $data->getCall(); and here I would like get PID
            unset(self::$runningApi[$call->getPid()]);
        }, function ($data) {
          if ($data instanceof CallDiedException) {
            $call = $data->getCall();
            unset(self::$runningApi[$call->getPid()]);
          }
        });
      }
  }
}

MyDaemon::getInstance()->setVerbose(true)->setDebug(true)->setLogFile('/tmp/MyDaemon.log')->run();

@lifo101
Copy link
Owner

lifo101 commented May 1, 2020

Why? The point of the Daemon is to encapsulate the details of how your workers are forked in the background.

When you create a Worker it can have many forked processes in the background, depending on how you set it up. So, getting a PID from the $worker variable would not be useful since you would only get a PID from one of the many forked processes w/o any relationship to whatever method you're calling.

However, Option 1: In your Worker code, you can add the PID to the returned array|object and act on it in the parent. For example, the getUrl function could return an array like so. But this is only partially useful, since you know the PID of a process that may not even exist anymore, or that PID may be used again for another call to your method (getUrl).

  public function getUrl($endPoint) {
    return [
      'pid' => getpid(),
      'url' => 'https://myurl.com/...'
    ];
  }

Option 2: I'm not sure what you're trying to achieve, but a better way to link the data you're passing to the forked method and your parent is to pass an 'ID' of some sort to the method and then return that same ID in the forked method. (eg: getUrl($id) => return ['url' => 'url', 'id' => $id]).

And btw, please look at the example in the Wiki where I catch the CallDiedException. This is one place you can see the PID of the process.

My advice, forget about PID's.

@lifo101 lifo101 closed this as completed Jun 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants