Skip to content

Commit 0c1d00d

Browse files
author
Johannes Weiss
committed
use NIOSingletons EventLoops/NIOThreadPool instead of spawning new
1 parent 62c06d4 commit 0c1d00d

9 files changed

+156
-116
lines changed

Package.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ let package = Package(
2121
.library(name: "AsyncHTTPClient", targets: ["AsyncHTTPClient"]),
2222
],
2323
dependencies: [
24-
.package(url: "https://github.com/apple/swift-nio.git", from: "2.50.0"),
24+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.58.0"),
2525
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.22.0"),
2626
.package(url: "https://github.com/apple/swift-nio-http2.git", from: "1.19.0"),
2727
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.13.0"),
28-
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.11.4"),
28+
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.19.0"),
2929
.package(url: "https://github.com/apple/swift-log.git", from: "1.4.4"),
3030
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.2"),
3131
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),

README.md

+10-14
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,10 @@ and `AsyncHTTPClient` dependency to your target:
2727

2828
The code snippet below illustrates how to make a simple GET request to a remote server.
2929

30-
Please note that the example will spawn a new `EventLoopGroup` which will _create fresh threads_ which is a very costly operation. In a real-world application that uses [SwiftNIO](https://github.com/apple/swift-nio) for other parts of your application (for example a web server), please prefer `eventLoopGroupProvider: .shared(myExistingEventLoopGroup)` to share the `EventLoopGroup` used by AsyncHTTPClient with other parts of your application.
31-
32-
If your application does not use SwiftNIO yet, it is acceptable to use `eventLoopGroupProvider: .createNew` but please make sure to share the returned `HTTPClient` instance throughout your whole application. Do not create a large number of `HTTPClient` instances with `eventLoopGroupProvider: .createNew`, this is very wasteful and might exhaust the resources of your program.
33-
3430
```swift
3531
import AsyncHTTPClient
3632

37-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
33+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
3834

3935
/// MARK: - Using Swift Concurrency
4036
let request = HTTPClientRequest(url: "https://apple.com/")
@@ -78,7 +74,7 @@ The default HTTP Method is `GET`. In case you need to have more control over the
7874
```swift
7975
import AsyncHTTPClient
8076

81-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
77+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
8278
do {
8379
var request = HTTPClientRequest(url: "https://apple.com/")
8480
request.method = .POST
@@ -103,7 +99,7 @@ try await httpClient.shutdown()
10399
```swift
104100
import AsyncHTTPClient
105101

106-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
102+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
107103
defer {
108104
try? httpClient.syncShutdown()
109105
}
@@ -129,15 +125,15 @@ httpClient.execute(request: request).whenComplete { result in
129125
### Redirects following
130126
Enable follow-redirects behavior using the client configuration:
131127
```swift
132-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,
128+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton,
133129
configuration: HTTPClient.Configuration(followRedirects: true))
134130
```
135131

136132
### Timeouts
137133
Timeouts (connect and read) can also be set using the client configuration:
138134
```swift
139135
let timeout = HTTPClient.Configuration.Timeout(connect: .seconds(1), read: .seconds(1))
140-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,
136+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton,
141137
configuration: HTTPClient.Configuration(timeout: timeout))
142138
```
143139
or on a per-request basis:
@@ -151,7 +147,7 @@ The following example demonstrates how to count the number of bytes in a streami
151147

152148
#### Using Swift Concurrency
153149
```swift
154-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
150+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
155151
do {
156152
let request = HTTPClientRequest(url: "https://apple.com/")
157153
let response = try await httpClient.execute(request, timeout: .seconds(30))
@@ -251,7 +247,7 @@ asynchronously, while reporting the download progress at the same time, like in
251247
example:
252248

253249
```swift
254-
let client = HTTPClient(eventLoopGroupProvider: .createNew)
250+
let client = HTTPClient(eventLoopGroupProvider: .singleton)
255251
let request = try HTTPClient.Request(
256252
url: "https://swift.org/builds/development/ubuntu1804/latest-build.yml"
257253
)
@@ -275,7 +271,7 @@ client.execute(request: request, delegate: delegate).futureResult
275271
### Unix Domain Socket Paths
276272
Connecting to servers bound to socket paths is easy:
277273
```swift
278-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
274+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
279275
httpClient.execute(
280276
.GET,
281277
socketPath: "/tmp/myServer.socket",
@@ -285,7 +281,7 @@ httpClient.execute(
285281

286282
Connecting over TLS to a unix domain socket path is possible as well:
287283
```swift
288-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
284+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
289285
httpClient.execute(
290286
.POST,
291287
secureSocketPath: "/tmp/myServer.socket",
@@ -312,7 +308,7 @@ The exclusive use of HTTP/1 is possible by setting `httpVersion` to `.http1Only`
312308
var configuration = HTTPClient.Configuration()
313309
configuration.httpVersion = .http1Only
314310
let client = HTTPClient(
315-
eventLoopGroupProvider: .createNew,
311+
eventLoopGroupProvider: .singleton,
316312
configuration: configuration
317313
)
318314
```

Sources/AsyncHTTPClient/Docs.docc/index.md

+34-15
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,13 @@ and `AsyncHTTPClient` dependency to your target:
3131

3232
The code snippet below illustrates how to make a simple GET request to a remote server.
3333

34-
Please note that the example will spawn a new `EventLoopGroup` which will _create fresh threads_ which is a very costly operation. In a real-world application that uses [SwiftNIO](https://github.com/apple/swift-nio) for other parts of your application (for example a web server), please prefer `eventLoopGroupProvider: .shared(myExistingEventLoopGroup)` to share the `EventLoopGroup` used by AsyncHTTPClient with other parts of your application.
35-
36-
If your application does not use SwiftNIO yet, it is acceptable to use `eventLoopGroupProvider: .createNew` but please make sure to share the returned `HTTPClient` instance throughout your whole application. Do not create a large number of `HTTPClient` instances with `eventLoopGroupProvider: .createNew`, this is very wasteful and might exhaust the resources of your program.
37-
3834
```swift
3935
import AsyncHTTPClient
4036

41-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
37+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
38+
defer {
39+
try! httpClient.shutdown().wait()
40+
}
4241

4342
/// MARK: - Using Swift Concurrency
4443
let request = HTTPClientRequest(url: "https://apple.com/")
@@ -82,7 +81,11 @@ The default HTTP Method is `GET`. In case you need to have more control over the
8281
```swift
8382
import AsyncHTTPClient
8483

85-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
84+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
85+
defer {
86+
try! httpClient.syncShutdown()
87+
}
88+
8689
do {
8790
var request = HTTPClientRequest(url: "https://apple.com/")
8891
request.method = .POST
@@ -107,9 +110,9 @@ try await httpClient.shutdown()
107110
```swift
108111
import AsyncHTTPClient
109112

110-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
113+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
111114
defer {
112-
try? httpClient.syncShutdown()
115+
try! httpClient.syncShutdown()
113116
}
114117

115118
var request = try HTTPClient.Request(url: "https://apple.com/", method: .POST)
@@ -133,15 +136,15 @@ httpClient.execute(request: request).whenComplete { result in
133136
#### Redirects following
134137
Enable follow-redirects behavior using the client configuration:
135138
```swift
136-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,
139+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton,
137140
configuration: HTTPClient.Configuration(followRedirects: true))
138141
```
139142

140143
#### Timeouts
141144
Timeouts (connect and read) can also be set using the client configuration:
142145
```swift
143146
let timeout = HTTPClient.Configuration.Timeout(connect: .seconds(1), read: .seconds(1))
144-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,
147+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton,
145148
configuration: HTTPClient.Configuration(timeout: timeout))
146149
```
147150
or on a per-request basis:
@@ -155,7 +158,11 @@ The following example demonstrates how to count the number of bytes in a streami
155158

156159
##### Using Swift Concurrency
157160
```swift
158-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
161+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
162+
defer {
163+
try! httpClient.syncShutdown()
164+
}
165+
159166
do {
160167
let request = HTTPClientRequest(url: "https://apple.com/")
161168
let response = try await httpClient.execute(request, timeout: .seconds(30))
@@ -255,7 +262,11 @@ asynchronously, while reporting the download progress at the same time, like in
255262
example:
256263

257264
```swift
258-
let client = HTTPClient(eventLoopGroupProvider: .createNew)
265+
let client = HTTPClient(eventLoopGroupProvider: .singleton)
266+
defer {
267+
try! httpClient.syncShutdown()
268+
}
269+
259270
let request = try HTTPClient.Request(
260271
url: "https://swift.org/builds/development/ubuntu1804/latest-build.yml"
261272
)
@@ -279,7 +290,11 @@ client.execute(request: request, delegate: delegate).futureResult
279290
#### Unix Domain Socket Paths
280291
Connecting to servers bound to socket paths is easy:
281292
```swift
282-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
293+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
294+
defer {
295+
try! httpClient.syncShutdown()
296+
}
297+
283298
httpClient.execute(
284299
.GET,
285300
socketPath: "/tmp/myServer.socket",
@@ -289,7 +304,11 @@ httpClient.execute(
289304

290305
Connecting over TLS to a unix domain socket path is possible as well:
291306
```swift
292-
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
307+
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
308+
defer {
309+
try! httpClient.syncShutdown()
310+
}
311+
293312
httpClient.execute(
294313
.POST,
295314
secureSocketPath: "/tmp/myServer.socket",
@@ -316,7 +335,7 @@ The exclusive use of HTTP/1 is possible by setting ``HTTPClient/Configuration/ht
316335
var configuration = HTTPClient.Configuration()
317336
configuration.httpVersion = .http1Only
318337
let client = HTTPClient(
319-
eventLoopGroupProvider: .createNew,
338+
eventLoopGroupProvider: .singleton,
320339
configuration: configuration
321340
)
322341
```

0 commit comments

Comments
 (0)