Skip to content

Commit 1a709e2

Browse files
authored
Merge pull request #226 from WyriHaximus-labs/global-event-loop-accessor-part-four
Global event-loop accessor part four
2 parents 8bd064c + b6e704a commit 1a709e2

18 files changed

+246
-97
lines changed

README.md

+30-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ single [`run()`](#run) call that is controlled by the user.
1313

1414
* [Quickstart example](#quickstart-example)
1515
* [Usage](#usage)
16+
* [Loop](#loop)
17+
* [get()](#get)
1618
* [Factory](#factory)
1719
* [create()](#create)
1820
* [Loop implementations](#loop-implementations)
@@ -45,32 +47,32 @@ single [`run()`](#run) call that is controlled by the user.
4547
Here is an async HTTP server built with just the event loop.
4648

4749
```php
48-
$loop = React\EventLoop\Factory::create();
50+
use React\EventLoop\Loop;
4951

5052
$server = stream_socket_server('tcp://127.0.0.1:8080');
5153
stream_set_blocking($server, false);
5254

53-
$loop->addReadStream($server, function ($server) use ($loop) {
55+
Loop::get()->addReadStream($server, function ($server) {
5456
$conn = stream_socket_accept($server);
5557
$data = "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nHi\n";
56-
$loop->addWriteStream($conn, function ($conn) use (&$data, $loop) {
58+
Loop::get()->addWriteStream($conn, function ($conn) use (&$data) {
5759
$written = fwrite($conn, $data);
5860
if ($written === strlen($data)) {
5961
fclose($conn);
60-
$loop->removeWriteStream($conn);
62+
Loop::get()->removeWriteStream($conn);
6163
} else {
6264
$data = substr($data, $written);
6365
}
6466
});
6567
});
6668

67-
$loop->addPeriodicTimer(5, function () {
69+
Loop::get()->addPeriodicTimer(5, function () {
6870
$memory = memory_get_usage() / 1024;
6971
$formatted = number_format($memory, 3).'K';
7072
echo "Current memory usage: {$formatted}\n";
7173
});
7274

73-
$loop->run();
75+
Loop::get()->run();
7476
```
7577

7678
See also the [examples](examples).
@@ -110,6 +112,28 @@ $loop->run();
110112
purposes.
111113
3. The loop is run with a single [`$loop->run()`](#run) call at the end of the program.
112114

115+
### Loop
116+
117+
The `Loop` class exists as a convenient global accessor for the event loop.
118+
119+
#### get()
120+
121+
The `get(): LoopInterface` method is the preferred way to get and use the event loop. With
122+
it there is no need to always pass the loop around anymore.
123+
124+
```php
125+
use React\EventLoop\Loop;
126+
127+
Loop::get()->addTimer(0.02, function () {
128+
echo 'World!';
129+
});
130+
Loop::get()->addTimer(0.01, function () {
131+
echo 'Hello ';
132+
});
133+
134+
Loop::get()->run();
135+
```
136+
113137
### Factory
114138

115139
The `Factory` class exists as a convenient way to pick the best available

examples/01-timers.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<?php
22

3-
require __DIR__ . '/../vendor/autoload.php';
3+
use React\EventLoop\Loop;
44

5-
$loop = React\EventLoop\Factory::create();
5+
require __DIR__ . '/../vendor/autoload.php';
66

7-
$loop->addTimer(0.8, function () {
7+
Loop::get()->addTimer(0.8, function () {
88
echo 'world!' . PHP_EOL;
99
});
1010

11-
$loop->addTimer(0.3, function () {
11+
Loop::get()->addTimer(0.3, function () {
1212
echo 'hello ';
1313
});
1414

15-
$loop->run();
15+
Loop::get()->run();

examples/02-periodic.php

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<?php
22

3-
require __DIR__ . '/../vendor/autoload.php';
3+
use React\EventLoop\Loop;
44

5-
$loop = React\EventLoop\Factory::create();
5+
require __DIR__ . '/../vendor/autoload.php';
66

7-
$timer = $loop->addPeriodicTimer(0.1, function () {
7+
$timer = Loop::get()->addPeriodicTimer(0.1, function () {
88
echo 'tick!' . PHP_EOL;
99
});
1010

11-
$loop->addTimer(1.0, function () use ($loop, $timer) {
12-
$loop->cancelTimer($timer);
11+
Loop::get()->addTimer(1.0, function () use ($timer) {
12+
Loop::get()->cancelTimer($timer);
1313
echo 'Done' . PHP_EOL;
1414
});
1515

16-
$loop->run();
16+
Loop::get()->run();

examples/03-ticks.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<?php
22

3-
require __DIR__ . '/../vendor/autoload.php';
3+
use React\EventLoop\Loop;
44

5-
$loop = React\EventLoop\Factory::create();
5+
require __DIR__ . '/../vendor/autoload.php';
66

7-
$loop->futureTick(function () {
7+
Loop::get()->futureTick(function () {
88
echo 'b';
99
});
10-
$loop->futureTick(function () {
10+
Loop::get()->futureTick(function () {
1111
echo 'c';
1212
});
1313
echo 'a';
1414

15-
$loop->run();
15+
Loop::get()->run();

examples/04-signals.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
<?php
22

3+
use React\EventLoop\Loop;
4+
35
require __DIR__ . '/../vendor/autoload.php';
46

57
if (!defined('SIGINT')) {
68
fwrite(STDERR, 'Not supported on your platform (ext-pcntl missing or Windows?)' . PHP_EOL);
79
exit(1);
810
}
911

10-
$loop = React\EventLoop\Factory::create();
11-
12-
$loop->addSignal(SIGINT, $func = function ($signal) use ($loop, &$func) {
12+
Loop::get()->addSignal(SIGINT, $func = function ($signal) use (&$func) {
1313
echo 'Signal: ', (string)$signal, PHP_EOL;
14-
$loop->removeSignal(SIGINT, $func);
14+
Loop::get()->removeSignal(SIGINT, $func);
1515
});
1616

1717
echo 'Listening for SIGINT. Use "kill -SIGINT ' . getmypid() . '" or CTRL+C' . PHP_EOL;
1818

19-
$loop->run();
19+
Loop::get()->run();

examples/11-consume-stdin.php

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
use React\EventLoop\Factory;
3+
use React\EventLoop\Loop;
44

55
require __DIR__ . '/../vendor/autoload.php';
66

@@ -9,16 +9,14 @@
99
exit(1);
1010
}
1111

12-
$loop = Factory::create();
13-
1412
// read everything from STDIN and report number of bytes
1513
// for illustration purposes only, should use react/stream instead
16-
$loop->addReadStream(STDIN, function ($stream) use ($loop) {
14+
Loop::get()->addReadStream(STDIN, function ($stream) {
1715
$chunk = fread($stream, 64 * 1024);
1816

1917
// reading nothing means we reached EOF
2018
if ($chunk === '') {
21-
$loop->removeReadStream($stream);
19+
Loop::get()->removeReadStream($stream);
2220
stream_set_blocking($stream, true);
2321
fclose($stream);
2422
return;
@@ -27,4 +25,4 @@
2725
echo strlen($chunk) . ' bytes' . PHP_EOL;
2826
});
2927

30-
$loop->run();
28+
Loop::get()->run();

examples/12-generate-yes.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
use React\EventLoop\Loop;
4+
35
require __DIR__ . '/../vendor/autoload.php';
46

57
// data can be given as first argument or defaults to "y"
@@ -8,22 +10,20 @@
810
// repeat data X times in order to fill around 200 KB
911
$data = str_repeat($data, round(200000 / strlen($data)));
1012

11-
$loop = React\EventLoop\Factory::create();
12-
1313
if (!defined('STDOUT') || stream_set_blocking(STDOUT, false) !== true) {
1414
fwrite(STDERR, 'ERROR: Unable to set STDOUT non-blocking (not CLI or Windows?)' . PHP_EOL);
1515
exit(1);
1616
}
1717

1818
// write data to STDOUT whenever its write buffer accepts data
1919
// for illustrations purpose only, should use react/stream instead
20-
$loop->addWriteStream(STDOUT, function ($stdout) use ($loop, &$data) {
20+
Loop::get()->addWriteStream(STDOUT, function ($stdout) use (&$data) {
2121
// try to write data
2222
$r = fwrite($stdout, $data);
2323

2424
// nothing could be written despite being writable => closed
2525
if ($r === 0) {
26-
$loop->removeWriteStream($stdout);
26+
Loop::get()->removeWriteStream($stdout);
2727
fclose($stdout);
2828
stream_set_blocking($stdout, true);
2929
fwrite(STDERR, 'Stopped because STDOUT closed' . PHP_EOL);
@@ -38,4 +38,4 @@
3838
}
3939
});
4040

41-
$loop->run();
41+
Loop::get()->run();

examples/13-http-client-blocking.php

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
<?php
22

3-
use React\EventLoop\Factory;
3+
use React\EventLoop\Loop;
44

55
require __DIR__ . '/../vendor/autoload.php';
66

7-
$loop = Factory::create();
8-
97
// connect to www.google.com:80 (blocking call!)
108
// for illustration purposes only, should use react/socket instead
119
$stream = stream_socket_client('tcp://www.google.com:80');
@@ -18,18 +16,18 @@
1816
fwrite($stream, "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n");
1917

2018
// wait for HTTP response
21-
$loop->addReadStream($stream, function ($stream) use ($loop) {
19+
Loop::get()->addReadStream($stream, function ($stream) {
2220
$chunk = fread($stream, 64 * 1024);
2321

2422
// reading nothing means we reached EOF
2523
if ($chunk === '') {
2624
echo '[END]' . PHP_EOL;
27-
$loop->removeReadStream($stream);
25+
Loop::get()->removeReadStream($stream);
2826
fclose($stream);
2927
return;
3028
}
3129

3230
echo $chunk;
3331
});
3432

35-
$loop->run();
33+
Loop::get()->run();

examples/14-http-client-async.php

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
<?php
22

33
use React\EventLoop\Factory;
4+
use React\EventLoop\Loop;
45

56
require __DIR__ . '/../vendor/autoload.php';
67

7-
$loop = Factory::create();
8-
98
// resolve hostname before establishing TCP/IP connection (resolving DNS is still blocking here)
109
// for illustration purposes only, should use react/socket or react/dns instead!
1110
$ip = gethostbyname('www.google.com');
@@ -24,14 +23,14 @@
2423

2524
// print progress every 10ms
2625
echo 'Connecting';
27-
$timer = $loop->addPeriodicTimer(0.01, function () {
26+
$timer = Loop::get()->addPeriodicTimer(0.01, function () {
2827
echo '.';
2928
});
3029

3130
// wait for connection success/error
32-
$loop->addWriteStream($stream, function ($stream) use ($loop, $timer) {
33-
$loop->removeWriteStream($stream);
34-
$loop->cancelTimer($timer);
31+
Loop::get()->addWriteStream($stream, function ($stream) use ($timer) {
32+
Loop::get()->removeWriteStream($stream);
33+
Loop::get()->cancelTimer($timer);
3534

3635
// check for socket error (connection rejected)
3736
if (stream_socket_get_name($stream, true) === false) {
@@ -45,13 +44,13 @@
4544
fwrite($stream, "GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n");
4645

4746
// wait for HTTP response
48-
$loop->addReadStream($stream, function ($stream) use ($loop) {
47+
Loop::get()->addReadStream($stream, function ($stream) {
4948
$chunk = fread($stream, 64 * 1024);
5049

5150
// reading nothing means we reached EOF
5251
if ($chunk === '') {
5352
echo '[END]' . PHP_EOL;
54-
$loop->removeReadStream($stream);
53+
Loop::get()->removeReadStream($stream);
5554
fclose($stream);
5655
return;
5756
}
@@ -60,4 +59,4 @@
6059
});
6160
});
6261

63-
$loop->run();
62+
Loop::get()->run();

examples/21-http-server.php

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22

3-
require __DIR__ . '/../vendor/autoload.php';
3+
use React\EventLoop\Loop;
44

5-
$loop = React\EventLoop\Factory::create();
5+
require __DIR__ . '/../vendor/autoload.php';
66

77
// start TCP/IP server on localhost:8080
88
// for illustration purposes only, should use react/socket instead
@@ -13,24 +13,24 @@
1313
stream_set_blocking($server, false);
1414

1515
// wait for incoming connections on server socket
16-
$loop->addReadStream($server, function ($server) use ($loop) {
16+
Loop::get()->addReadStream($server, function ($server) {
1717
$conn = stream_socket_accept($server);
1818
$data = "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nHi\n";
19-
$loop->addWriteStream($conn, function ($conn) use (&$data, $loop) {
19+
Loop::get()->addWriteStream($conn, function ($conn) use (&$data) {
2020
$written = fwrite($conn, $data);
2121
if ($written === strlen($data)) {
2222
fclose($conn);
23-
$loop->removeWriteStream($conn);
23+
Loop::get()->removeWriteStream($conn);
2424
} else {
2525
$data = substr($data, $written);
2626
}
2727
});
2828
});
2929

30-
$loop->addPeriodicTimer(5, function () {
30+
Loop::get()->addPeriodicTimer(5, function () {
3131
$memory = memory_get_usage() / 1024;
3232
$formatted = number_format($memory, 3).'K';
3333
echo "Current memory usage: {$formatted}\n";
3434
});
3535

36-
$loop->run();
36+
Loop::get()->run();

examples/91-benchmark-ticks.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
<?php
22

3-
use React\EventLoop\Factory;
3+
use React\EventLoop\Loop;
44

55
require __DIR__ . '/../vendor/autoload.php';
66

7-
$loop = Factory::create();
8-
97
$n = isset($argv[1]) ? (int)$argv[1] : 1000 * 100;
108

119
for ($i = 0; $i < $n; ++$i) {
12-
$loop->futureTick(function () { });
10+
Loop::get()->futureTick(function () { });
1311
}
1412

15-
$loop->run();
13+
Loop::get()->run();

0 commit comments

Comments
 (0)