profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/PeterAdams-A/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.

swift-server/async-http-client 447

HTTP client library built on SwiftNIO

PeterAdams-A/async-http-client 0

HTTP client library built on SwiftNIO

PeterAdams-A/grpc 0

The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)

PeterAdams-A/grpc-swift 0

The Swift language implementation of gRPC.

PeterAdams-A/sswg 0

Swift Server Working Group (SSWG)

PeterAdams-A/swift-log 0

A Logging API for Swift

PeterAdams-A/swift-nio 0

Event-driven network application framework for high performance protocol servers & clients, non-blocking.

PeterAdams-A/swift-nio-examples 0

examples of how to use swift-nio

PeterAdams-A/swift-nio-extras 0

Useful code around SwiftNIO.

PeterAdams-A/swift-nio-http2 0

HTTP/2 support for SwiftNIO

Pull request review commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

 func main() async {         print(", response:", String(buffer: response2.body ?? ByteBuffer()))          try await channel.close()++        try await group.shutdownGracefully()

Lemme add the shutdown to the catch.

simonjbeaumont

comment created time in an hour

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

@swift-nio-bot add to allowlist

simonjbeaumont

comment created time in an hour

Pull request review commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

 func main() async {         print(", response:", String(buffer: response2.body ?? ByteBuffer()))          try await channel.close()++        try await group.shutdownGracefully()

Yeah, you can't await in a defer. In this case, a do...catch is probably easier.

simonjbeaumont

comment created time in an hour

Pull request review commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

 extension EventLoopFuture {     } } +extension EventLoopGroup {+    /// Shuts down the event loop gracefully.+    @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)+    @inlinable+    public func shutdownGracefully() async throws {+        return try await withCheckedThrowingContinuation { cont in+            self.shutdownGracefully { error in+                if let error = error {+                    cont.resume(throwing: error)+                }+                cont.resume()

Of course, oops. I forgot the early-return/switch/else here. Total fail 😅.

simonjbeaumont

comment created time in an hour

Pull request review commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

 func main() async {         print(", response:", String(buffer: response2.body ?? ByteBuffer()))          try await channel.close()++        try await group.shutdownGracefully()

Yes, I noticed this.

I wasn't able able to use the defer shutdown with the async, and because the comments said it was safe to call shutdown twice, I thought the safest thing to do was to leave the top-level shutdown.

I'll move the group lifecycle into the async function, though as it's probably the right thing to do.

simonjbeaumont

comment created time in an hour

Pull request review commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

 func main() async {         print(", response:", String(buffer: response2.body ?? ByteBuffer()))          try await channel.close()++        try await group.shutdownGracefully()

This patch isn't quite right as we now shut the loop down twice. Can you move the existing event loop construction out of the top-level scope and into this async function instead?

simonjbeaumont

comment created time in 2 hours

Pull request review commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

 extension EventLoopFuture {     } } +extension EventLoopGroup {+    /// Shuts down the event loop gracefully.+    @available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)+    @inlinable+    public func shutdownGracefully() async throws {+        return try await withCheckedThrowingContinuation { cont in+            self.shutdownGracefully { error in+                if let error = error {+                    cont.resume(throwing: error)+                }+                cont.resume()

Continuations must be resumed exactly once: this will fail in the event we hit the error path, as we'll resume twice.

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

pull request commentapple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Can one of the admins verify this patch?

simonjbeaumont

comment created time in 2 hours

PR opened apple/swift-nio

Add async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

Adds a new extension to EventLoopGroup in _NIOConcurrency to provide an asynchronous shutdownGracefully().

Motivation

Shutting down an event loop was special because it used a completion handler and executed on a DispatchQueue because there would be no event loop to use an EventLoopFuture.

Now we have the new Swift concurrency features, we can provide an async shutdownGracefully.

Fixes #1878.

Modifications

Adds EventLoopGroup.shutdownGracefully() async and some code to use it in NIOAsyncAwaitDemo.

There's no obvious way to ask an ELG if it has been shutdown but I made the following local-only changes to verify that this performs as expected:

diff --git a/Sources/NIO/EventLoop.swift b/Sources/NIO/EventLoop.swift
index d18a33dd..972b3b05 100644
--- a/Sources/NIO/EventLoop.swift
+++ b/Sources/NIO/EventLoop.swift
@@ -840 +840 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
-    private enum RunState {
+    public enum RunState {
@@ -852 +852 @@ public final class MultiThreadedEventLoopGroup: EventLoopGroup {
-    private var runState: RunState = .running
+    public var runState: RunState = .running
diff --git a/Sources/NIOAsyncAwaitDemo/main.swift b/Sources/NIOAsyncAwaitDemo/main.swift
index 97a9c0c3..f8b29ace 100644
--- a/Sources/NIOAsyncAwaitDemo/main.swift
+++ b/Sources/NIOAsyncAwaitDemo/main.swift
@@ -60,0 +61 @@ func main() async {
+        print("elg state: \(group.runState)")  // .running
@@ -61,0 +63,7 @@ func main() async {
+        print("elg state: \(group.runState)")  // .closed(nil)
+
+        /// This causes the following error:
+        /// ERROR: Cannot schedule tasks on an EventLoop that has already shut down. This will be upgraded to a forced crash in future SwiftNIO versions.
+        group.next().execute {
+            print("This will not execute.")
+        }
+19 -0

0 comment

2 changed files

pr created time in 2 hours

issue openedapple/swift-nio

Add an async implementation of EventLoopGroup.shutdownGracefully to _NIOConcurrency

EventLoopGroups sometimes need to be shutdown gracefully. This operation does not return a future (as it has no loop to execute on) but instead uses a callback. We can provide a nice async wrapper of this fairly easily by using withCheckedThrowingContinuation.

created time in 3 days

push eventapple/swift-nio

buttaface

commit sha a1f405285a3bc3e4e9289bb62372f60adbd82e73

Fix tests for 32-bit platforms, tested for Android armv7 (#1877) Motivation: Get the tests passing on 32-bit platforms again. Modifications: - Change the way _UInt56.max is initialized. - Set the proper max capacity for AdaptiveRecvByteBufferAllocator and change the test to match it. - Add a cmsghdrExample for Android armv7. Result: All the same tests pass on Android armv7 as Android AArch64.

view details

push time in 3 days

PR merged apple/swift-nio

Fix tests for 32-bit platforms, tested for Android armv7 patch-version-bump-only

Motivation:

Get the tests passing on 32-bit platforms again.

Modifications:

  • Change the way _UInt56.max is initialized.
  • Set the proper max capacity for AdaptiveRecvByteBufferAllocator and change the test to match it.
  • Add a cmsghdrExample for Android armv7.

Result:

All the same tests pass on Android armv7 as Android AArch64.

Now that I have a working Android armv7 5.4 toolchain again, termux/termux-packages#6941, I noticed that the armv7 tests had regressed since February. These changes got me to parity with AArch64, ie only BootstrapTest/testClientBindWorksOnSocketsBoundToEitherIPv4OrIPv6Only fails now, will look into that later.

+26 -9

15 comments

4 changed files

buttaface

pr closed time in 3 days

pull request commentapple/swift-nio

Fix tests for 32-bit platforms, tested for Android armv7

@swift-nio-bot add to allowlist

buttaface

comment created time in 3 days

Pull request review commentapple/swift-nio

Fix tests for 32-bit platforms, tested for Android armv7

 final class AdaptiveRecvByteBufferAllocatorTest: XCTestCase {         }          let adaptive = AdaptiveRecvByteBufferAllocator(minimum: targetValue, initial: targetValue + 1, maximum: targetValue + 2)-        XCTAssertEqual(adaptive.minimum, 1 << 31)-        XCTAssertEqual(adaptive.maximum, 1 << 31)-        XCTAssertEqual(adaptive.initial, 1 << 31)+        XCTAssertEqual(adaptive.minimum, 1 << 30)+        XCTAssertEqual(adaptive.maximum, 1 << 30)+        XCTAssertEqual(adaptive.initial, 1 << 30)

I had initially missed these tests that aren't run on armv7, got them after testing this pull on Android AArch64 too.

buttaface

comment created time in 4 days

Pull request review commentapple/swift-nio

Fix tests for 32-bit platforms, tested for Android armv7

 final class AdaptiveRecvByteBufferAllocatorTest: XCTestCase {         self.adaptive = AdaptiveRecvByteBufferAllocator(minimum: 0, initial: .max / 2, maximum: .max)         var mayGrow = true         while mayGrow {-            mayGrow = self.adaptive.record(actualReadBytes: .max)+            mayGrow = self.adaptive.record(actualReadBytes: .max / 2 )

OK, with that last change, this test change is no longer needed. Added the check you suggested and removed this halving in latest commit.

buttaface

comment created time in 4 days

Pull request review commentapple/swift-nio

Fix tests for 32-bit platforms, tested for Android armv7

 final class AdaptiveRecvByteBufferAllocatorTest: XCTestCase {         self.adaptive = AdaptiveRecvByteBufferAllocator(minimum: 0, initial: .max / 2, maximum: .max)         var mayGrow = true         while mayGrow {-            mayGrow = self.adaptive.record(actualReadBytes: .max)+            mayGrow = self.adaptive.record(actualReadBytes: .max / 2 )

Oh, line 105 of RecvByteBufferAllocator needs an extra check: it needs to check that self.nextReceiveBufferSize != upperBound. Otherwise this isn't growing at all.

buttaface

comment created time in 4 days

Pull request review commentapple/swift-nio

Fix tests for 32-bit platforms, tested for Android armv7

 final class AdaptiveRecvByteBufferAllocatorTest: XCTestCase {         self.adaptive = AdaptiveRecvByteBufferAllocator(minimum: 0, initial: .max / 2, maximum: .max)         var mayGrow = true         while mayGrow {-            mayGrow = self.adaptive.record(actualReadBytes: .max)+            mayGrow = self.adaptive.record(actualReadBytes: .max / 2 )

Made that change to check if upperBoundCandidate is negative, but I still had to make this change to the test. Otherwise, the nextReceiveBufferSize correctly maxes out at 2^30 and this test loop becomes an infinite loop: I guess because it can never reach Int32.max.

buttaface

comment created time in 4 days