A SIG_Routine object indicates to the processor a routine that must be run.
Each routine is ran at the beginning of the loop.
It allows for giving the processor the following information.
- Signals to emit
- How to idle until the next loop
SIG_Routines are designed for signals that will need to idle the processor
to wait for emitting in the future.
/** * Constructs a new suite. */ public function __construct($function) { if ($function instanceof Closure) { throw new InvalidArgumentException(); } parent::__construct(); $this->_test = new SIG_Test(spl_object_hash($this)); $function($this); }
/** * Constructs a awake signal. * * @param int $time Amount of time before emitting the signal. * * @throws InvalidArgumentException * * @return void */ public function __construct($time, $instruction = TIME_SECONDS) { if ((!is_int($time) || !is_float($time)) && $time < 0) { throw new \InvalidArgumentException("Time must be greater than 0"); } parent::__construct(); $this->_time = $time; $this->_instruction = $instruction; $this->set_idle(new Time($time, $instruction)); }
/** * Constructs a new cron signal. * * @param string $expression Cron expression * * @throws InvalidArgumentException * * @return void */ public function __construct($expression) { if (!HAS_CRONEXPRESSION) { throw new \RuntimeException("Cron-Expression library is required for cron signals - https://github.com/mtdowling/cron-expression"); } $this->_cron = \Cron\CronExpression::factory($expression); $this->_next_run = $this->_cron->getNextRunDate()->getTimestamp(); $this->set_idle(new Time($this->_next_run - time(), TIME_SECONDS)); parent::__construct(); }
/** * Construct the routine that must be run. * * @param array $files Files to upload * @param array $options FTP Connection options. * * @return void */ public function __construct($files, $options = []) { parent::__construct(); $this->_sig_complete = new SIG_Complete(); $this->_sig_failure = new SIG_Failure(); $this->_sig_finished = new SIG_Finished($this); $defaults = ['hostname' => null, 'port' => 21, 'timeout' => 90, 'username' => null, 'password' => null, 'secure' => false]; $this->_files = $files; $options += $defaults; $this->_options = $options; /** * Upload Idle process */ $this->_idle = new Process(function () { $this->_init_transfers(); foreach ($this->_uploading as $_key => $_file) { $status = ftp_nb_continue($_file[0]); if ($status === FTP_MOREDATA) { continue; } if ($status === FTP_FINISHED) { $this->_sig_complete->set_upload($_file[1]); xp_emit($this->_sig_complete); // Close the FTP connection to that file ftp_close($_file[0]); $this->_uploaded[] = $_file[1]; } else { $this->_sig_failure->set_upload($_file[1]); xp_emit($this->_sig_failure); // Close the FTP connection to that file ftp_close($_file[0]); } unset($this->_uploading[$_key]); } // Cleanup once finished if (count($this->_uploading) == 0) { xp_emit($this->_sig_finished); xp_delete_signal($this); xp_delete_signal($this->_sig_complete); xp_delete_signal($this->_sig_failure); } }); // Init xp_emit($this); }
/** * Constructs a new socket. * * @param string $address Address to make the connection on. * @param string $options Connection options * * @return void */ public function __construct($address, $options = []) { parent::__construct(); $defaults = ['port' => null, 'domain' => AF_INET, 'type' => SOCK_STREAM, 'protocol' => SOL_TCP]; $options += $defaults; $this->_address = $address; $this->_options = $options; /** * TODO * * Shorten this entire loop. */ $this->_idle = new Process(function ($processor) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug('Entering socket wait loop'); } $idle = $processor->get_routine()->get_idles_available(); // 30 second default wait $time = 30; $utime = 0; // Determine if another function has requested to execute in x // amount of time if (count($processor->get_routine()->get_signals()) !== 0) { // If we have signals to process only poll and continue $time = 0; } elseif (count($idle) >= 2) { $default_wait_time = time() + $this->default_wait_time; foreach ($idle as $_idle) { // if ($_idle->get_idle() instanceof Time) { // // echo $default_wait_time.PHP_EOL; // // echo $_idle->get_idle()->get_time_until().PHP_EOL; // // echo $_idle->get_idle()->get_time_until() < $default_wait_time.PHP_EOL; // // echo $_idle->get_idle()->get_time_until() > $default_wait_time.PHP_EOL; // // echo $_idle.PHP_EOL; // } // if ($_idle->get_idle() instanceof Time && ( // // $default_wait_time > $_idle->get_idle()->get_time_until())) { // // $time = round($_idle->get_idle()->convert_length( // // $_idle->get_idle()->get_time_left(), // // TIME_SECONDS // // ), 3); // // if ($time > 0 && $time < 1) { // // $utime = $time * 1000; // // $time = 0; // // } // // echo $time.PHP_EOL; // // break; // } } } // establish sockets $re = [$this->_connection->get_resource()]; $wr = $ex = []; foreach ($this->_clients as $_k => $_c) { $_resource = $_c->get_resource(); // test if socket is still connected // send disconnect if disconnect detected if ($_c->is_connected() === false) { xp_emit(new SIG_Disconnect($_c)); unset($this->_clients[$_k]); continue; } else { $re[] = $_resource; $ex[] = $_resource; } } $count = socket_select($re, $wr, $ex, $time, $utime); if ($count === false) { logger(XPSPL_LOG)->debug('Socket wait loop ended PROBLEM'); return false; } elseif ($count == 0) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug('Socket wait loop ended no connection changes'); } return true; } if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug('Socket wait loop ended connection changes detected'); } // Check Read if (count($re) !== 0) { foreach ($re as $_r) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug(sprintf('Connection Read %s', strval(intval($_r)))); } $id = intval($_r); if (!isset($this->_clients[$id])) { $client = new Client($_r); $id = intval($client->get_resource()); xp_emit(new SIG_Connect($this, $client)); $this->_clients[$id] = $client; if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug(sprintf('Added Connection %s', strval(intval($id)))); } } else { $this->_clients[$id]->_read_buffer(); xp_emit(new SIG_Read($this, $this->_clients[$id])); } } } // Check Write if (count($wr) !== 0) { foreach ($wr as $_write) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug(sprintf('Connection Write %s', strval($_write))); } $processor->get_routine()->add_signal(new SIG_Write($this, $this->_clients[intval($_write)])); } } // Errors if (count($ex) !== 0) { foreach ($ex as $_excep) { if (XPSPL_DEBUG) { logger(XPSPL_LOG)->debug(sprintf('Connection Exception %s', strval($_excep))); } $this->_clients[intval($_excep)]->error = socket_last_error($_excep); $this->_clients[intval($_excep)]->error_str = socket_strerror($_excep); $processor->get_routine()->add_signal(new SIG_Error($this, $this->_clients[intval($_excep)])); } } }); $this->on_disconnect(xp_priority(PHP_INT_MAX, '\\network\\system_disconnect')); // After processing read clean the buffer xp_after(new SIG_Read($this), xp_low_priority('\\network\\clean_buffer')); // Emit this has started xp_emit($this); }
/** * Constructs a new test signal. * * @param string $name Name of the test. * * @return void */ public function __construct($name = null) { $this->_index = 'test-' . $name . '-'; $this->name = $name; parent::__construct(); }
public function __construct() { $this->_idle = new \XPSPL\idle\Threads(0, TIME_SECONDS); parent::__construct(); }