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

Add support for signal handling #104

Merged
merged 1 commit into from
Nov 10, 2017

Conversation

WyriHaximus
Copy link
Member

@WyriHaximus WyriHaximus commented Jul 25, 2017

This PR adds OS signal handling. There are a few things of discussion, I'll post comments on the representing code lines.

Signal handlers:

@WyriHaximus WyriHaximus added this to the v0.5.0 milestone Jul 25, 2017
@WyriHaximus WyriHaximus requested review from jsor and clue July 25, 2017 16:59
@WyriHaximus WyriHaximus changed the title Stoplichten OS signaling Jul 25, 2017
public function on($signal, callable $listener)
{
if (!$this->enabled) {
return;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to fail silently or do we want to throw an exception?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should throw, otherwise an app cannot depend on signal handling.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaning towards the same, most other options add either more methods or silently fail and the consumer doesn't have clue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing an exception also makes sense to me 👍

}

if ($this->timer === null) {
$this->timer = $this->loop->addPeriodicTimer(0.1, function () {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is checking for signals 10 times a second enough or should we do it 25 times a second or X per second?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling pcntl_signal_dispatch() can simply be rolled into the main event loop after calling stream_select(), since the latter is interrupted by the arrival of signals, regardless of the timeout parameter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check, but that would only be for the stream_select() loop right? As the other have signaling build in

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I made that comment before I realized you were using the object with other loop implementations. Integrating it into StreamSelectLoop should be the eventual goal then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, integration into the event loop is the ultimate goal here 👍

In the meantime, 0.1s is either too slow or too fast depending on what you're doing, so we may as well add an argument or constant at least.

public function testSignal()
{
if (!extension_loaded('pcntl')) {
$this->markTestSkipped('Signal test skipped because PCNTL extension isn\'t loaded.');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another way around the support of PCNTL would be an extra method that could be called to check if the loop supports signals. Thoughts?

Copy link

@trowski trowski Jul 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could… though if an app depends on signals, likely it will throw anyway, so may as well throw from the onSignal() method. Note that libevent, libev, and libuv support signal handling without the need of the pcntl extension.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that libevent, libev, and libuv support signal handling without the need of the pcntl extension.

Yeah it's on the list for this PR 😎


public function __construct()
{
$this->loop = new EventLoop();
$this->futureTickQueue = new FutureTickQueue();
$this->timerEvents = new SplObjectStorage();
$this->signals = new Pcntl($this);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LibEvLoop should use the signal handling provided by the extension, as it is more reliable and integrates with the loop backend being used by the extension. Same goes for LibEventLoop and ExtEventLoop.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's on the list at the top ^ 😎

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so it is, missed that when focusing on the diff. 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem, your input is much appreciated 👍

Copy link
Member

@clue clue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I really like this feature and the direction this is heading! 👍 I think @trowski made some very good points about integration with other event loop implementations here 👍

README.md Outdated
be notified about OS signals. This is useful to catch user interrupt signals or
shutdown signals from tools like `supervisor` or `systemd`.

The
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover?

*
* @return void
*/
public function onSignal($signal, callable $listener);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be named addSignal() for consistency with other methods?

Also, the docs should probably include whether multiple listeners can be attached to the same signal?

*
* @return void
*/
public function removeSignal($signal, callable $listener);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the same listener be added multiple times? If so, which one will be removed here?

Also, the docs should probably include what happens if the given signal or listener is not attached (NO-OP just like other methods?).

public function on($signal, callable $listener)
{
if (!$this->enabled) {
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing an exception also makes sense to me 👍

}

if ($this->timer === null) {
$this->timer = $this->loop->addPeriodicTimer(0.1, function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, integration into the event loop is the ultimate goal here 👍

In the meantime, 0.1s is either too slow or too fast depending on what you're doing, so we may as well add an argument or constant at least.

});

$this->loop->futureTick(function () {
posix_kill(posix_getpid(), SIGUSR1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that these functions may be disabled http://php.net/manual/en/posix.installation.php

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this is a unit test I'm not that worried. Might put an if and fail in the if the function isn't available

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just skip the test if it isn't available.

@WyriHaximus
Copy link
Member Author

@clue @trowski Reworked the signal handling for stream_select to use PCNTL and the other loops to use the signaling provided by the underlying loops.

The question is what to do with trying to add the same listener more then once. We can either throw, ignore it silently, or just allow it. I've written it now in such a way that the latter works (or better should work, added tests for it this afternoon) and also removes all occurrences of a listener when you remove it.

@WyriHaximus
Copy link
Member Author

Had to rework the signal handler because not all loops support using the same listener more then once. That has all been resolve now and they all behave the same 😎 . Personally I think this would be the most transparent way of dealing the reused listeners.

$this->signalEvents[$signal]->add();
});
$this->signals->on('off', function ($signal) {
$this->futureTick(function () use ($signal) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be in a future tick? This looks unexpected from a consumer perspective and would at least need some documentation here? I haven't verified this, but it looks like this could potentially cause a race condition, can you verify this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, the issue is that certain loops throw errors when you try to remove a signal handler while handling the given signal. In order to mitigate the race condition each loop does a check to ensure there are no registered signal handlers for the given signal. Should add documentation for it.

composer.json Outdated
@@ -4,15 +4,17 @@
"keywords": ["event-loop", "asynchronous"],
"license": "MIT",
"require": {
"php": ">=5.4.0"
"php": ">=5.4.0",
"evenement/evenement": "^3.0||^2.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this dependency is used throughout the ecosystem, but is it really worth it or should we try to keep this component stand-alone?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well given the signal handler only has an on and an off even called once we don't really need it. I'll refactor and remove it.

README.md Outdated

**Note: A listener can be added more then once to the same signal and it will be called
for each time it is added. But on [`removeSignal`](#removeSignal) it is removed for all
the times it has been added.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior looks really odd to me. Does it make sense to either reject adding the same listener multiple times or only remove a single instance so adding/removing behaves consistent?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, it should either error out or have another mechanism for removing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing a single instance would be easy to do. But it might be more consistent to only allow one occurrence of a instance per signal in the first place.

composer.json Outdated
},
"require-dev": {
"phpunit/phpunit": "~4.8"
},
"suggest": {
"ext-libevent": ">=0.1.0",
"ext-event": "~1.0",
"ext-libev": "*"
"ext-libev": "*",
"ext-pcntl": "For signals support"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Afaict this is only need for the default loop, right? Documentation should probably be updated to explicitly say when this extension is recommended?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, I assume you mean the documentation here and in README.md. I'll update both

*
* @throws UnsupportedFeatureException when signals
* aren't supported by the loop, e.g. when required
* extensions are missing.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this method really throw? Looks like adding isn't possible in this case either, so this actually boils down to removing a non-existent listener?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is more about consistency between two methods than it is likely someone will call this method when addSignal throws.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think that this situation shouldn't throw. Removing a non-existent listener does not throw, so why would removing a listener throw when it's impossible to add listeners in the first place?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me, they can catch the exception when trying top add it. I'll remove the exception on removing signal listeners 👍

@@ -196,6 +237,9 @@ private function waitForStreamActivity($timeout)
$write = $this->writeStreams;

$available = $this->streamSelect($read, $write, $timeout);
if ($this->pcntl) {
\pcntl_signal_dispatch();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be checked after every loop iteration and does this cause any performance issues? It's my understanding that a signal would interrupt the select() call checked below, no?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A signal interrupts stream_select(), correct.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signals aren't picked up when I change if ($this->pcntl) { into if (false === $available && $this->pcntl) {only dispatching when the loop received a signal. Not aware of any performance degradations.

if (isset($this->signals[$signal]) && \count($this->signals[$signal]) === 0) {
unset($this->signals[$signal]);
$this->emit('off', [$signal]);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That if can be moved below the while loop, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, kinda depends on the result of the discussion here: #104 (comment)

$this->signals->on('on', function ($signal) {
\pcntl_signal($signal, function ($signal) {
$this->signals->call($signal);
});
Copy link
Contributor

@kelunik kelunik Aug 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That traps the signal and installs a process-wide handler. I guess it should at least be cleaned up in something like __destruct(). Behavior with multiple loops needs to be defined somehow.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@kelunik
Copy link
Contributor

kelunik commented Aug 14, 2017

That traps the signal and installs a process-wide handler. I guess it should at least be cleaned up in something like __destruct(). Behavior with multiple loops needs to be defined somehow.

Repeating that comment so it doesn't get hidden by changes.

@WyriHaximus
Copy link
Member Author

@clue @kelunik Updated the PR after your comments with changes taking those in mind

@kelunik
Copy link
Contributor

kelunik commented Aug 24, 2017

@WyriHaximus why are duplicates silently ignored instead of erroring out?

@WyriHaximus
Copy link
Member Author

@kelunik because it is consistent with how stream callables are handled

Copy link
Member

@jsor jsor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved from a user presepective and delegating technical approval to @clue.

@WyriHaximus
Copy link
Member Author

Ping @clue

@clue clue removed the easy pick label Oct 11, 2017
Copy link
Member

@clue clue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the direction this is heading! Only added some minor remarks:


$loop = React\EventLoop\Factory::create();

$loop->onSignal(SIGINT, $func = function ($signal) use ($loop, &$func) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outdated?

$this->signalEvents[$signal]->add();
},
function ($signal) {
$this->futureTick(function () use ($signal) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, why does this use futureTick() and what consequence does this have? (see also below)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In come loops removing the signal handled within the function handling a signal will make it fail hard. Another way would be to use future tick in the SignalHandler when receiving the signal but that means the SignalHandler becomes aware of the event loop.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you provide a gist that shows this problem? Reading the documentation of our event loop implementations I could not find anything that supports this claim.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm odd can't reproduce is niet 🤐 . I'll remove the ticks

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I'll add them again because this is what happens: https://travis-ci.org/reactphp/event-loop/jobs/290513376#L1401

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting find! Looks like this was actually bug in PHP (https://bugs.php.net/bug.php?id=62452) that was fixed with PHP 7. Removing this in the next tick has some consequences, so I wonder if this can be worked around by keeping a reference to the closure instead (see also the PHP bug for some workarounds).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clue yeah also know why I couldn't see it locally, didn't ran the tests on 5.6 locally 🤐 . Just committed a possible fix, since I can't test locally I'm going to run them on Travis and squash the commits once fixed if it needs more then one try.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clue resolved the issue 🎉

*
* @throws UnsupportedFeatureException when signals
* aren't supported by the loop, e.g. when required
* extensions are missing.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think that this situation shouldn't throw. Removing a non-existent listener does not throw, so why would removing a listener throw when it's impossible to add listeners in the first place?

{
return new self('Event loop feature "' . $feature . '" isn\'t supported by the "' . $loopName . '" event loop');
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds the first custom exception to this package, so I would much rather discuss this in a separate PR and remove here for now? 👍 A BadMethodCallException seems to be a good replacement for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Bad method call?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kelunik What was your suggestion again?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception thrown if a callback refers to an undefined method or if some arguments are missing.

BadMethodCallException is usually used in combination with __call, not if requirements for a call are missing.

My suggestion is to keep a custom exception that makes things clear.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clue personally I moving more and more towards custom exceptions for each use case so the error handled in a specific manner for that error. Maybe we should have a discussion about if we want that in ReactPHP before adding a custom exception to a packages. I'll change it unless you and @jsor prefer this idea of a custom exception per error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not suggesting that "custom exception per error" is not a good idea (see above), merely that I think it makes sense to discuss this in a separate ticket because I would love to get this feature in already :shipit: :-) Also note that this is the first method can may throw in the first place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright I've swap it out with a core exception and we can have this discussion in another issue so we can get this feature in :shipit:


final class SignalsHandlerTest extends TestCase
{
public function testEmittedEventsAndCallHandling()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signal constants are only defined when PCNTL is loaded: http://php.net/manual/en/pcntl.constants.php

This test should probably check for this first. Also, maybe add a remark about this to the README?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defining in tests/bootstrap.php when they don't exist in case PCNTL isn't loaded


if (!defined('SIGUSR2')) {
define('SIGUSR2', 2);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about making a package both Amp and ReactPHP can use that polyfills the signal constants?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For two constants not really. Seems way to much overhead tbh.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not only those two. It's also for using them with other reactor implementations if pcntl isn't available.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kelunik I agree with @WyriHaximus, this is probably overkill for this test suite. But I agree that it may make sense for consumers that want to rely on signal constant names, so I'd suggest go for it and create that package :shipit:

@@ -10,6 +10,7 @@
$loop->stop();
});

// This timer is here to keep the loop alive, signaling an-sich doesn't do that
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an-sich -> by ifself

@kelunik
Copy link
Contributor

kelunik commented Oct 12, 2017

@WyriHaximus Could you add a test that a signal watcher doesn't keep the loop running if no other watcher exists?

@WyriHaximus
Copy link
Member Author

@kelunik just added the test and waiting for the results from travis

{
public static function create($feature, $loopName)
{
return new self('Event loop feature "' . $feature . '" isn\'t supported by the "' . $loopName . '" event loop');
Copy link
Contributor

@kelunik kelunik Oct 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go for a regular constructor here. The message should probably cover why the feature isn't supported (missing ext-pcntl). The $loopName should also be the class name instead of "stream_select" IMO, but I'd argue that it's not needed in the message, because the used implementation will show up in the stack trace.

@WyriHaximus
Copy link
Member Author

Ping @clue

README.md Outdated
@@ -292,6 +292,37 @@ echo 'a';

See also [example #3](examples).

### addSignal()

**Note: Signaling is only available on Unix-like platform, Windows isn't supported.**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it makes sense to not support Windows in the first step. 👍

However, note that others (https://docs.python.org/3/library/signal.html#signal.signal or nodejs/node-v0.x-archive#1553) do provide limited, simulated signal handling supports on Windows. As such, I would suggest moving this note down a bit and make it more clear that this is not an interface limitations.

We should probably document the exception that we throw when signal handling is not supported. This should also cover Windows compatibility.

See also [example #4](examples).

**Note: A listener can only be added once to the same signal, any attempts to add it
more then once will be ignored.**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No objection to this limitation, but I would suggest making sure this is closer to the verbiage for our stream API (https://github.com/reactphp/event-loop/pull/110/files#diff-04c6e90faac2675aa89e2176d2eec7d8R312). What do you think about this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated it, it isn't my strongest skill and I rather not let it block this PR thus I suggest if it needs work I do it in a follow up PR.

$this->loop->addTimer(0.1, function () {});

$this->assertRunFasterThan(0.2);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

$loop->stop();
});

// This timer is here to keep the loop alive, signaling by itself doesn't do that
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears unexpected to me and is apparently undocumented. I'm curious for the reasoning and documentation here, as I would clearly have expected this to behave otherwise. What is the motivation for not making this "keep the loop alive"? (Keeping consistency with other event loop listeners in mind here)

Also note that this is related to #107.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The motivation to not keeping the loop alive with signals was that there where not inputs into the loop kicking off more activity besides the signals. But now that I think about it signals COULD be used to kick off more activity. I'll update this PR shortly using a timer to keep the loop alive as long as signals are registered to it.

@WyriHaximus
Copy link
Member Author

@clue reworked the PR so signals now keep the loop running

$loop->addSignal(SIGINT, $func = function ($signal) use ($loop, &$func) {
echo 'Signal: ', (string)$signal, PHP_EOL;
$loop->removeSignal(SIGINT, $func);
$loop->stop();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The $loop->stop() doesn't do any harm, but it's not really needed anymore, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope no need for it there \o/

{
if (count($this->signals) == 0 && $this->timer === null) {
$this->timer = $this->loop->addPeriodicTimer(1, function () {});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest using a much higher interval do prevent the CPU from waking up every second. Also, maybe add a simple comment what this does?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't really see the harm in once a second but increased it to five minutes

WyriHaximus added a commit to WyriHaximus-labs/event-loop that referenced this pull request Nov 4, 2017
WyriHaximus added a commit to WyriHaximus-labs/event-loop that referenced this pull request Nov 4, 2017
@WyriHaximus
Copy link
Member Author

@clue updated as per your comments 👍

@WyriHaximus
Copy link
Member Author

@clue solved merge conflict, could you review again?

Copy link
Member

@clue clue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome job @WyriHaximus! 🎉 This should be squashed to a reasonable number of commits, otherwise LGTM! :shipit: 🎉

$ git fetch origin
$ git checkout stoplichten
$ git rebase -i origin/master
# squash/fixup as applicable

@clue clue changed the title OS signaling Add support for signal handling Nov 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants