forked from pradosoft/prado
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pradosoft#972 TProcessHelper, TSignalsDispatcher, and related classes…
… & functions - TProcessHelper for process related functions like forking (pcntl_fork) and isSystemWindows(). - TSignalsDispatcher for raising signal related global events from signals for multiple handlers per signal, alarm and disarm callbacks at a specific time (1 second precision), and for callbacks per child processes (proc_open, pcntl_fork, etc) when they end (or "stop and start"?). - ISingleton is a new interface for application singleton objects - TShellWriter is updated to use the TProcessHelper::isSystemWindows function -TComponent only hasMethod of global event handlers that do actually exist. As a global event it exists always, but not the method. - TEventSubscription example is updated to reflect TSignalsDispatcher and TSignalParameter - TApplicationSignals behavior for configuration and attaching of TSignalsDispatcher - TCaptureForkLog behavior for capturing the logs of forked child processes in the main log. Effectively a ForkLogRouter but registering as a behavior on TApplication. - TForkable behavior for attaching the owner's ::fxPrepareForFork() and ::fxRestoreAfterFork() handlers to their respective global events. -TGlobalClassAware behavior for attaching the owner's ::fxAttachClassBehavior() and ::fxDetachClassBehavior() to their respective global events so they change with global class changes without listening. - TProcessWindowsPriority specifies the numeric priorities that windows uses for each respective priority level. - TProcessWindowsPriorityName specifies the text priorities that windows uses for each respective priority level.
- Loading branch information
Showing
28 changed files
with
3,277 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
/** | ||
* ISingleton interface file. | ||
* | ||
* @author Brad Anderson <[email protected]> | ||
* @link https://github.com/pradosoft/prado | ||
* @license https://github.com/pradosoft/prado/blob/master/LICENSE | ||
*/ | ||
|
||
namespace Prado; | ||
|
||
/** | ||
* ISingleton interface. | ||
* | ||
* This interface is for getting specific class (application) singletons. | ||
* | ||
* @author Brad Anderson <[email protected]> | ||
* @since 4.2.3 | ||
*/ | ||
interface ISingleton | ||
{ | ||
/** | ||
* @param bool $create Should the singleton be created if it doesn't exist. | ||
* @return ?object The singleton instance of the class | ||
*/ | ||
public static function singleton(bool $create = true): ?object; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
* @author Qiang Xue <[email protected]> | ||
* | ||
* Global Events, intra-object events, Class behaviors, expanded behaviors | ||
* @author Brad Anderson <javalizard@mac.com> | ||
* @author Brad Anderson <belisoful@icloud.com> | ||
* | ||
* @author Qiang Xue <[email protected]> | ||
* @link https://github.com/pradosoft/prado | ||
|
@@ -1136,7 +1136,7 @@ protected function getCallChain($method, ...$args): ?TCallChain | |
*/ | ||
public function hasMethod($name) | ||
{ | ||
if (Prado::method_visible($this, $name) || strncasecmp($name, 'fx', 2) === 0 || strncasecmp($name, 'dy', 2) === 0) { | ||
if (Prado::method_visible($this, $name) || strncasecmp($name, 'dy', 2) === 0) { | ||
return true; | ||
} elseif ($this->_m !== null && $this->getBehaviorsEnabled()) { | ||
foreach ($this->_m->toArray() as $behavior) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
<?php | ||
/** | ||
* TApplicationSignals class file. | ||
* | ||
* @author Brad Anderson <[email protected]> | ||
* @link https://github.com/pradosoft/prado | ||
* @license https://github.com/pradosoft/prado/blob/master/LICENSE | ||
*/ | ||
|
||
namespace Prado\Util\Behaviors; | ||
|
||
use Prado\Exceptions\TInvalidDataValueException; | ||
use Prado\Exceptions\TInvalidOperationException; | ||
use Prado\TComponent; | ||
use Prado\TPropertyValue; | ||
use Prado\Util\TBehavior; | ||
use Prado\Util\TSignalsDispatcher; | ||
|
||
/** | ||
* TApplicationSignals class. | ||
* | ||
* This behavior installs the {@see \Prado\Util\TSignalsDispatcher} (or subclass) for | ||
* the application when PHP pcntl_* is available. The signals dispatcher class can | ||
* be specified with {@see self::setSignalsClass()} and is installed when the TApplicationSignals | ||
* behavior is attached to the TApplication owner. | ||
* | ||
* There is a TSignalsDispatcher getter {@see self::getSignalsDispatcher} added to | ||
* the owner (TApplication) for retrieving the dispatcher. | ||
* | ||
* There are two properties of TApplicationSignals for TSignalsDispatcher. {@see | ||
* self::setAsyncSignals} changes how signals are handled. When synchronous, | ||
* {@see \Prado\Util\TSignalsDispatcher::syncDispatch()} must be called for signals | ||
* to be processed. When asynchronous, the signals will be handled by atomic interrupt. | ||
* | ||
* ```xml | ||
* <behavior name="appSignals" AttachToClass="Prado\TApplication" class="Prado\Util\Behaviors\TApplicationSignals" PriorHandlerPriority="5" /> | ||
* ``` | ||
* | ||
* @author Brad Anderson <[email protected]> | ||
* @since 4.2.3 | ||
*/ | ||
class TApplicationSignals extends TBehavior | ||
{ | ||
/** @var string the signals class. */ | ||
protected ?string $_signalsClass = null; | ||
|
||
/** | ||
* Attaches the TSignalsDispatcher to handle the process signals. | ||
* @param TComponent $component The owner. | ||
* @return bool Should the behavior's event handlers be attached. | ||
*/ | ||
protected function attachEventHandlers(TComponent $component): bool | ||
{ | ||
if ($return = parent::attachEventHandlers($component)) { | ||
($this->getSignalsClass())::singleton(); | ||
} | ||
return $return; | ||
} | ||
|
||
/** | ||
* Detaches the TSignalsDispatcher from handling the process signals. | ||
* @param TComponent $component The owner. | ||
* @return bool Should the behavior's event handlers be detached. | ||
*/ | ||
protected function detachEventHandlers(TComponent $component): bool | ||
{ | ||
if ($return = parent::detachEventHandlers($component)) { | ||
if ($dispatcher = ($this->getSignalsClass())::singleton(false)) { | ||
$dispatcher->detach(); | ||
unset($dispatcher); | ||
} | ||
} | ||
return $return; | ||
} | ||
|
||
/** | ||
* @return ?object The Signal Dispatcher. | ||
*/ | ||
public function getSignalsDispatcher(): ?object | ||
{ | ||
return ($this->getSignalsClass())::singleton(false); | ||
} | ||
|
||
/** | ||
* @return ?string The class of the Signals Dispatcher. | ||
*/ | ||
public function getSignalsClass(): ?string | ||
{ | ||
if ($this->_signalsClass === null) { | ||
$this->_signalsClass = TSignalsDispatcher::class; | ||
} | ||
|
||
return $this->_signalsClass; | ||
} | ||
|
||
/** | ||
* @param ?string $value The class of the Signals Dispatcher. | ||
* @throws TInvalidOperationException When already attached, this cannot be changed. | ||
* @throws TInvalidDataValueException When the class is not a TSignalsDispatcher. | ||
* @return static The current object. | ||
*/ | ||
public function setSignalsClass($value): static | ||
{ | ||
if ($this->getOwner()) { | ||
throw new TInvalidOperationException('appsignals_no_change', 'SignalsClass'); | ||
} | ||
if ($value === '') { | ||
$value = null; | ||
} | ||
|
||
if ($value !== null) { | ||
$value = TPropertyValue::ensureString($value); | ||
if (!is_a($value, TSignalsDispatcher::class, true)) { | ||
throw new TInvalidDataValueException('appsignals_not_a_dispatcher', $value); | ||
} | ||
} | ||
|
||
$this->_signalsClass = $value; | ||
|
||
return $this; | ||
} | ||
|
||
/** | ||
* @return bool Is the system executing signal handlers asynchronously. | ||
*/ | ||
public function getAsyncSignals(): bool | ||
{ | ||
return ($this->getSignalsClass())::getAsyncSignals(); | ||
} | ||
|
||
/** | ||
* @param mixed $value Set the system to execute signal handlers asynchronously (or synchronously on false). | ||
* @return bool Was the system executing signal handlers asynchronously. | ||
*/ | ||
public function setAsyncSignals($value): bool | ||
{ | ||
return ($this->getSignalsClass())::setAsyncSignals(TPropertyValue::ensureBoolean($value)); | ||
} | ||
|
||
/** | ||
* When the original signal handlers are placed into the Signals Events this is the | ||
* priority of original signal handlers. | ||
* @return ?float The priority of the signal handlers that were installed before | ||
* the TSignalsDispatcher attaches. | ||
*/ | ||
public function getPriorHandlerPriority(): ?float | ||
{ | ||
return ($this->getSignalsClass())::getPriorHandlerPriority(); | ||
} | ||
|
||
/** | ||
* @param null|float|string $value The priority of the signal handlers that were installed before | ||
* the TSignalsDispatcher attaches. | ||
* @return bool Is the Prior Handler Priority changed. | ||
*/ | ||
public function setPriorHandlerPriority($value): bool | ||
{ | ||
if ($value === '') { | ||
$value = null; | ||
} | ||
if ($value !== null) { | ||
$value = TPropertyValue::ensureFloat($value); | ||
} | ||
return ($this->getSignalsClass())::setPriorHandlerPriority($value); | ||
} | ||
} |
Oops, something went wrong.