Skip to content

Commit 585c382

Browse files
committed
Disable Nagle's algorithm in some examples
1 parent 7aa962b commit 585c382

4 files changed

Lines changed: 35 additions & 12 deletions

File tree

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,15 @@ $server->stop();
136136

137137
The above example creates a simple server which sends a plain-text response to every request received.
138138

139+
> **Note**
140+
> Nagle's algorithm can negatively affect benchmarks on some systems. It can be disabled using `Amp\Socket\BindContext::withTcpNoDelay()`, passing the returned instance as the second argument to `SocketHttpServer::expose()`.
141+
139142
`SocketHttpServer` provides two static constructors for common use-cases in addition to the normal constructor for more advanced and custom uses.
140143

141-
- `SocketHttpServer::createForDirectAccess()`: Used in the example above, this creates an HTTP application server suitable for direct network access. Adjustable limits are imposed on connections per IP, total connections, and concurrent requests (10, 1000, and 1000 by default, respectively). Response compression may be toggled on or off (on by default) and request methods are limited to a known set of HTTP verbs by default.
142-
- `SocketHttpServer::createForBehindProxy()`: Creates a server appropriate for use when behind a proxy service such as nginx. This static constructor requires a list of trusted proxy IPs (with optional subnet masks) and an enum case of `ForwardedHeaderType` (corresponding to either `Forwarded` or `X-Forwarded-For`) to parse the original client IP from request headers. No limits are imposed on the number of connections to the server, however the number of concurrent requests are limited (1000 by default, adjustable or can be removed). Response compression may be toggled on or off (on by default). Request methods are limited to a known set of HTTP verbs by default.
144+
- `SocketHttpServer::createForDirectAccess()`: Used in the example above, this creates an HTTP application server suitable for direct network access. Adjustable limits are imposed on connections per IP, total connections, and concurrent requests (10, 1000, and 1000 by default, respectively). Response compression may be toggled on or off (on by default), and request methods are limited to a known set of HTTP verbs by default.
145+
- `SocketHttpServer::createForBehindProxy()`: Creates a server appropriate for use when behind a proxy service such as nginx. This static constructor requires a list of trusted proxy IPs (with optional subnet masks) and an enum case of `ForwardedHeaderType` (corresponding to either `Forwarded` or `X-Forwarded-For`) to parse the original client IP from request headers. No limits are imposed on the number of connections to the server, however the number of concurrent requests is limited (1000 by default, adjustable or can be removed). Response compression may be toggled on or off (on by default). Request methods are limited to a known set of HTTP verbs by default.
143146

144-
If neither of these methods serve your application needs, the `SocketHttpServer` constructor may be used directly. This provides an enormous amount of flexibility in how incoming connections client connections are created and handled, but will require more code to create. The constructor requires the user to pass an instance of `SocketServerFactory`, used to create client `Socket` instances (both components of the [`amphp/socket`](https://github.com/amphp/socket) library), and an instance of `ClientFactory`, which appropriately creates [`Client`](#request-clients) instances which are attached to each `Request` made by the client.
147+
If neither of these methods serves your application needs, the `SocketHttpServer` constructor may be used directly. This provides an enormous amount of flexibility in how incoming client connections are created and handled, but will require more code to create. The constructor requires the user to pass an instance of `SocketServerFactory`, used to create client `Socket` instances (both components of the [`amphp/socket`](https://github.com/amphp/socket) library), and an instance of `ClientFactory`, which appropriately creates [`Client`](#request-clients) instances which are attached to each `Request` made by the client.
145148

146149
### `RequestHandler`
147150

examples/event-source.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Amp\Http\Server\SocketHttpServer;
1414
use Amp\Log\ConsoleFormatter;
1515
use Amp\Log\StreamHandler;
16+
use Amp\Socket\BindContext;
1617
use Monolog\Logger;
1718
use Monolog\Processor\PsrLogMessageProcessor;
1819
use function Amp\delay;
@@ -48,8 +49,14 @@
4849

4950
$server = SocketHttpServer::createForDirectAccess($logger);
5051

51-
$server->expose("0.0.0.0:1337");
52-
$server->expose("[::]:1337");
52+
// BindContext::withTcpNoDelay() returns a context which disables Nagle's algorithm, decreasing
53+
// latency when responses are very small (as is the case here). This generally is not necessary
54+
// for a production server but can negatively affect benchmarks.
55+
56+
$bindContext = (new BindContext())->withTcpNoDelay();
57+
58+
$server->expose("0.0.0.0:1337", $bindContext);
59+
$server->expose("[::]:1337", $bindContext);
5360

5461
$server->start(new ClosureRequestHandler(function (Request $request) use ($html): Response {
5562
$path = $request->getUri()->getPath();

examples/hello-world.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Amp\Log\ConsoleFormatter;
1515
use Amp\Log\StreamHandler;
1616
use Amp\Socket;
17+
use Amp\Socket\BindContext;
1718
use Monolog\Logger;
1819
use Monolog\Processor\PsrLogMessageProcessor;
1920
use function Amp\trapSignal;
@@ -22,7 +23,12 @@
2223

2324
$cert = new Socket\Certificate(__DIR__ . '/../test/server.pem');
2425

25-
$context = (new Socket\BindContext)
26+
// BindContext::withTcpNoDelay() returns a context which disables Nagle's algorithm, decreasing
27+
// latency when responses are very small (as is the case here). This generally is not necessary
28+
// for a production server but can negatively affect benchmarks.
29+
$plainBindContext = (new BindContext)->withTcpNoDelay();
30+
31+
$tlsBindContext = $plainBindContext
2632
->withTlsContext((new Socket\ServerTlsContext)
2733
->withDefaultCertificate($cert));
2834

@@ -39,10 +45,10 @@
3945
new SocketClientFactory($logger),
4046
);
4147

42-
$server->expose("0.0.0.0:1337");
43-
$server->expose("[::]:1337");
44-
$server->expose("0.0.0.0:1338", $context);
45-
$server->expose("[::]:1338", $context);
48+
$server->expose("0.0.0.0:1337", $plainBindContext);
49+
$server->expose("[::]:1337", $plainBindContext);
50+
$server->expose("0.0.0.0:1338", $tlsBindContext);
51+
$server->expose("[::]:1338", $tlsBindContext);
4652

4753
$server->start(new class implements RequestHandler {
4854
public function handleRequest(Request $request): Response

examples/state.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Amp\Http\Server\SocketHttpServer;
1313
use Amp\Log\ConsoleFormatter;
1414
use Amp\Log\StreamHandler;
15+
use Amp\Socket\BindContext;
1516
use Monolog\Logger;
1617
use Monolog\Processor\PsrLogMessageProcessor;
1718
use function Amp\trapSignal;
@@ -24,10 +25,16 @@
2425
$logger = new Logger('server');
2526
$logger->pushHandler($logHandler);
2627

28+
// BindContext::withTcpNoDelay() returns a context which disables Nagle's algorithm, decreasing
29+
// latency when responses are very small (as is the case here). This generally is not necessary
30+
// for a production server but can negatively affect benchmarks.
31+
32+
$bindContext = (new BindContext())->withTcpNoDelay();
33+
2734
$server = SocketHttpServer::createForDirectAccess($logger);
2835

29-
$server->expose("0.0.0.0:1337");
30-
$server->expose("[::]:1337");
36+
$server->expose("0.0.0.0:1337", $bindContext);
37+
$server->expose("[::]:1337", $bindContext);
3138

3239
$server->start(new ClosureRequestHandler(function (Request $request): Response {
3340
static $counter = 0;

0 commit comments

Comments
 (0)