profile
viewpoint

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

PeterAdams-A/swift-nio-ssl 0

TLS Support for SwiftNIO, based on BoringSSL.

issue commentapple/swift-nio

Could not connect to local server from iOS simulator

@Davidde94, @weissi :

Thanks for your feedbacks.

Let me check again then let you know the result

hieunc278

comment created time in 2 hours

Pull request review commentapple/swift-nio

Remove last occurrences of sanity

 $sed -e 's/u_int\([0-9]\+\)_t/uint\1_t/g'      -e $'/__FBSDID/c #include "include/CNIOSHA1.h"\\n#include <string.h>\\n#if !defined(bzero)\\n#define bzero(b,l) memset((b), \'\\\\0\', (l))\\n#endif\\n#if !defined(bcopy)\\n#define bcopy(s,d,l) memmove((d), (s), (l))\\n#endif\\n#ifdef __ANDROID__\\n#include <sys/endian.h>\\n#elif __linux__\\n#include <sys/types.h>\\n#endif' \      -i "$here/c_nio_sha1.c"      -$sed -e 's/sanity check/soundness check/g' \+$sed -e 's/sanit[y]/soundness/g' \

fixed

fabianfett

comment created time in 4 hours

push eventapple/swift-nio

Fabian Fett

commit sha 6b41c18bf6418f7b1a6c00493dba1e80f54e1bb3

Fix Codec memory reclaim bug (#1729)

view details

push time in 5 hours

PR merged apple/swift-nio

B2MD: Fix default memory reclamation strategy to match its documentation patch-version-bump-only

In cases in which only a small amount of bytes were consumed from a ByteBuffer during decoding a small error in our logic could lead to extensive reclaims of memory, degrading the overall performance and allocating way to much memory.

Motivation:

  • In cases in which only a small amount was decoded from the ByteToMessageHandler's internal byteBuffer, we ran into reallocations based on our previous logic. If the byteBuffer was larger than 1kb and less than 50% were consumed we reallocated.
  • This leads to performance problems
  • But more importantly if within the decode function a byteBuffer slice is read, the internal ByteToMessageHandler's byteBuffer's storage is now referenced at multiple locations a leading to fast and excessive memory growth.

Modifications:

  • A logic bug has been fixed, we reclaim memory now, if more than 50% of the byteBuffer has been read.
  • The tests have been adjusted to reflect the fixed logic bug.

Result:

  • Faster decoding of small messages
  • Less memory footprint when reading slices in small messages.
+60 -9

0 comment

3 changed files

fabianfett

pr closed time in 5 hours

push eventgrpc/grpc-swift

George Barnett

commit sha 6f920564d9dc1770537500542c7b3fec3fd1ff53

Emit fewer flushes when handling RPCs on the server (#1110) Motivation: The changes in #1101 included a change in when flushes were emitted. For unary RPCs this led to an additional flush, which in some circumstances led to a drop in QPS of approximately 5%. Modifications: - Introduce an option as to whether a flush should be emitted when writing initial response metadata - Fix a bug where the request to flush or not for messages was ignored Result: A 5% increase in QPS for the unary-single benchmark (single connection, one rpc at a time).

view details

push time in 5 hours

PR merged grpc/grpc-swift

Emit fewer flushes when handling RPCs on the server semver-patch •

Motivation:

The changes in #1101 included a change in when flushes were emitted. For unary RPCs this led to an additional flush, which in some circumstances led to a drop in QPS of approximately 5%.

Modifications:

  • Introduce an option as to whether a flush should be emitted when writing initial response metadata
  • Fix a bug where the request to flush or not for messages was ignored

Result:

A 5% increase in QPS for the unary-single benchmark (single connection, one rpc at a time).

+31 -31

0 comment

8 changed files

glbrntt

pr closed time in 5 hours

Pull request review commentapple/swift-nio

Remove last occurrences of sanity

 $sed -e 's/u_int\([0-9]\+\)_t/uint\1_t/g'      -e $'/__FBSDID/c #include "include/CNIOSHA1.h"\\n#include <string.h>\\n#if !defined(bzero)\\n#define bzero(b,l) memset((b), \'\\\\0\', (l))\\n#endif\\n#if !defined(bcopy)\\n#define bcopy(s,d,l) memmove((d), (s), (l))\\n#endif\\n#ifdef __ANDROID__\\n#include <sys/endian.h>\\n#elif __linux__\\n#include <sys/types.h>\\n#endif' \      -i "$here/c_nio_sha1.c"      -$sed -e 's/sanity check/soundness check/g' \+$sed -e 's/sanit[y]/soundness/g' \

@fabianfett you could just add this line to the above sed. So just add

    -e 's/sanit[y]/soundness/g' \

into the above sed, then we only need one invocation

fabianfett

comment created time in 5 hours

Pull request review commentapple/swift-nio

B2MD: Fix default memory reclamation strategy to match its documentation

 extension ByteToMessageDecoder {     public func shouldReclaimBytes(buffer: ByteBuffer) -> Bool {         // We want to reclaim in the following cases:         //-        // 1. If there is more than 2kB of memory to reclaim+        // 1. If there is at least 2kB of memory to reclaim         // 2. If the buffer is more than 50% reclaimable memory and is at least         //    1kB in size.-        if buffer.readerIndex > 2048 {+        if buffer.readerIndex >= 2048 {             return true         }-        return buffer.capacity > 1024 && (buffer.capacity - buffer.readerIndex) >= buffer.readerIndex+        return buffer.capacity >= 1024 && (buffer.capacity - buffer.readerIndex) < buffer.readerIndex

thank you

fabianfett

comment created time in 6 hours

Pull request review commentapple/swift-nio

B2MD: Fix default memory reclamation strategy to match its documentation

 extension ByteToMessageDecoder {     public func shouldReclaimBytes(buffer: ByteBuffer) -> Bool {         // We want to reclaim in the following cases:         //-        // 1. If there is more than 2kB of memory to reclaim+        // 1. If there is at least 2kB of memory to reclaim         // 2. If the buffer is more than 50% reclaimable memory and is at least         //    1kB in size.-        if buffer.readerIndex > 2048 {+        if buffer.readerIndex >= 2048 {

offline discussion with Fabian:

  • the change in this logic is kinda arbitrary but it also won't hurt
  • the documentation is just a code comment and not in the public API docs so we never guaranteed what we'd do anyway so shifting the arbitrary limit by 1 byte shouldn't matter
fabianfett

comment created time in 6 hours

PR opened apple/swift-nio

Remove last occurrences of sanity

Final pr regarding using welcoming language. (Follow up to #1728 and #1731)

Modifications:

  • the soundness script now enforces that "sanity" isn't used anymore
  • the sanity build step has been removed from CI
  • fix to update_and_patch_sha1.sh so that it isn't flagged from the soundness script

Result:

SwiftNIO's language is more welcoming to developers from all backgrounds.

+2 -8

0 comment

3 changed files

pr created time in 7 hours

Pull request review commentapple/swift-nio

Replace unwelcoming language in sha1

 c_nio_sha1_pad(ctxt) }  void-c_nio_sha1_loop(ctxt, input, len)-	struct sha1_ctxt *ctxt;-	const uint8_t *input;-	size_t len;+c_nio_sha1_loop(struct sha1_ctxt *ctxt, const uint8_t *input, size_t len)

OMG, they migrated from K&R C to ANSII C!!! They caught up with 1989!!! the future

fabianfett

comment created time in 7 hours

Pull request review commentgrpc/grpc-swift

Emit fewer flushes when handling RPCs on the server

 internal final class HTTP2ToRawGRPCServerCodec: ChannelDuplexHandler, GRPCServer       // Always end stream for status and trailers.       let payload = HTTP2Frame.FramePayload.headers(.init(headers: trailers, endStream: true))       self.context.write(self.wrapOutboundOut(payload), promise: promise)--      if self.isReading {-        self.flushPending = true-      } else {-        self.context.flush()-      }+      // We'll always flush on end.+      self.markFlushPoint()      case let .failure(error):       promise?.fail(error)     }   }++  /// Mark a flush as pending - to be emitted once the read completes - if we're currently reading,+  /// or emit a flush now if we are not.+  private func markFlushPoint() {+    if self.isReading {+      self.flushPending = true+    } else {+      self.context.flush()

Oh never mind, I'm clearly looking in the wrong place.

glbrntt

comment created time in 9 hours

Pull request review commentgrpc/grpc-swift

Emit fewer flushes when handling RPCs on the server

 internal final class HTTP2ToRawGRPCServerCodec: ChannelDuplexHandler, GRPCServer       // Always end stream for status and trailers.       let payload = HTTP2Frame.FramePayload.headers(.init(headers: trailers, endStream: true))       self.context.write(self.wrapOutboundOut(payload), promise: promise)--      if self.isReading {-        self.flushPending = true-      } else {-        self.context.flush()-      }+      // We'll always flush on end.+      self.markFlushPoint()      case let .failure(error):       promise?.fail(error)     }   }++  /// Mark a flush as pending - to be emitted once the read completes - if we're currently reading,+  /// or emit a flush now if we are not.+  private func markFlushPoint() {+    if self.isReading {+      self.flushPending = true+    } else {+      self.context.flush()

For that matter, do we do anything with flushPending at all?

glbrntt

comment created time in 9 hours

Pull request review commentgrpc/grpc-swift

Emit fewer flushes when handling RPCs on the server

 internal final class HTTP2ToRawGRPCServerCodec: ChannelDuplexHandler, GRPCServer       // Always end stream for status and trailers.       let payload = HTTP2Frame.FramePayload.headers(.init(headers: trailers, endStream: true))       self.context.write(self.wrapOutboundOut(payload), promise: promise)--      if self.isReading {-        self.flushPending = true-      } else {-        self.context.flush()-      }+      // We'll always flush on end.+      self.markFlushPoint()      case let .failure(error):       promise?.fail(error)     }   }++  /// Mark a flush as pending - to be emitted once the read completes - if we're currently reading,+  /// or emit a flush now if we are not.+  private func markFlushPoint() {+    if self.isReading {+      self.flushPending = true+    } else {+      self.context.flush()

I don't think it's strictly necessary; we'll only set it when we're reading and we'll unset it before we flush in channel read complete. That said, that seems a little brittle and there's no harm in unsetting it here too.

glbrntt

comment created time in 9 hours

Pull request review commentgrpc/grpc-swift

Emit fewer flushes when handling RPCs on the server

 internal final class HTTP2ToRawGRPCServerCodec: ChannelDuplexHandler, GRPCServer       // Always end stream for status and trailers.       let payload = HTTP2Frame.FramePayload.headers(.init(headers: trailers, endStream: true))       self.context.write(self.wrapOutboundOut(payload), promise: promise)--      if self.isReading {-        self.flushPending = true-      } else {-        self.context.flush()-      }+      // We'll always flush on end.+      self.markFlushPoint()      case let .failure(error):       promise?.fail(error)     }   }++  /// Mark a flush as pending - to be emitted once the read completes - if we're currently reading,+  /// or emit a flush now if we are not.+  private func markFlushPoint() {+    if self.isReading {+      self.flushPending = true+    } else {+      self.context.flush()

Don't we need to unset flushPending here?

glbrntt

comment created time in 9 hours

push eventapple/swift-nio

Fabian Fett

commit sha 0260fc32cf5030ba547ac9c23c0913d82088f8db

Replace unwelcoming language in sha1 (#1731)

view details

push time in 9 hours

PR merged apple/swift-nio

Replace unwelcoming language in sha1 needs-no-version-bump

Follow up to #1728

Modifications:

  • In update_and_patch_sha1.sh we replace occurrences of sanity check with soundness check

Result:

c_nio_sha1.h and c_nio_sha1.c don't have manual changes anymore.

+10 -12

0 comment

3 changed files

fabianfett

pr closed time in 9 hours

PR opened apple/swift-nio

Replace unwelcoming language in sha1

Follow up to #1728

Modifications:

  • In update_and_patch_sha1.sh we replace occurrences of sanity check with soundness check

Result:

c_nio_sha1.h and c_nio_sha1.c don't have manual changes anymore.

+10 -12

0 comment

3 changed files

pr created time in 9 hours

issue openedapple/swift-nio

How about http3?

I was investigating http3/QUIC possibilities. Cannot find any examples of http3 stream api. Maybe in this repo will be ok to add it?

created time in 10 hours

Pull request review commentapple/swift-nio

B2MD: Fix default memory reclamation strategy to match its documentation

 public final class ByteToMessageDecoderTest: XCTestCase {         _ = try channel.pipeline.addHandler(decoder).wait()          // We're going to send in 513 bytes. This will cause a chunk to be passed on, and will leave-        // a 512-byte empty region in a 513 byte buffer. This will not cause a shrink.+        // a 512-byte empty region in a byte buffer with a capacity of 1024 bytes. Since 512 empty

Thank you! That makes sense.

fabianfett

comment created time in 10 hours

Pull request review commentapple/swift-nio

B2MD: Fix default memory reclamation strategy to match its documentation

 extension ByteToMessageDecoder {     public func shouldReclaimBytes(buffer: ByteBuffer) -> Bool {         // We want to reclaim in the following cases:         //-        // 1. If there is more than 2kB of memory to reclaim+        // 1. If there is at least 2kB of memory to reclaim         // 2. If the buffer is more than 50% reclaimable memory and is at least         //    1kB in size.-        if buffer.readerIndex > 2048 {+        if buffer.readerIndex >= 2048 {

Thank you! That makes sense.

fabianfett

comment created time in 10 hours

Pull request review commentapple/swift-nio

B2MD: Fix default memory reclamation strategy to match its documentation

 extension ByteToMessageDecoder {     public func shouldReclaimBytes(buffer: ByteBuffer) -> Bool {         // We want to reclaim in the following cases:         //-        // 1. If there is more than 2kB of memory to reclaim+        // 1. If there is at least 2kB of memory to reclaim         // 2. If the buffer is more than 50% reclaimable memory and is at least         //    1kB in size.-        if buffer.readerIndex > 2048 {+        if buffer.readerIndex >= 2048 {             return true         }-        return buffer.capacity > 1024 && (buffer.capacity - buffer.readerIndex) >= buffer.readerIndex+        return buffer.capacity >= 1024 && (buffer.capacity - buffer.readerIndex) < buffer.readerIndex

Fixed.

fabianfett

comment created time in 10 hours

Pull request review commentapple/swift-nio

B2MD: Fix default memory reclamation strategy to match its documentation

 public final class ByteToMessageDecoderTest: XCTestCase {         _ = try channel.pipeline.addHandler(decoder).wait()          // We're going to send in 513 bytes. This will cause a chunk to be passed on, and will leave-        // a 512-byte empty region in a 513 byte buffer. This will not cause a shrink.+        // a 512-byte empty region in a byte buffer with a capacity of 1024 bytes. Since 512 empty

With the fixed logic above this tests fails without modifications. For this reason, I adjusted it.

fabianfett

comment created time in 10 hours

Pull request review commentapple/swift-nio

B2MD: Fix default memory reclamation strategy to match its documentation

 extension ByteToMessageDecoder {     public func shouldReclaimBytes(buffer: ByteBuffer) -> Bool {         // We want to reclaim in the following cases:         //-        // 1. If there is more than 2kB of memory to reclaim+        // 1. If there is at least 2kB of memory to reclaim         // 2. If the buffer is more than 50% reclaimable memory and is at least         //    1kB in size.-        if buffer.readerIndex > 2048 {+        if buffer.readerIndex >= 2048 {

In CodecTests we currently explicitly test this behavior. The test succeeded up until now, since it used the buggy code path:

    func testMemoryIsReclaimedIfLotsIsAvailable() throws {
        let channel = EmbeddedChannel()
        defer {
            XCTAssertNoThrow(try channel.finish())
        }

        let decoder = ByteToMessageHandler(OnceDecoder()) // <--- the once decoder consumes exactly 2048 bytes.
        _ = try channel.pipeline.addHandler(decoder).wait()

        // We're going to send in 5119 bytes. This will be held.
        var buffer = channel.allocator.buffer(capacity: 5119)
        buffer.writeBytes(Array(repeating: 0x04, count: 5119))
        XCTAssertTrue(try channel.writeInbound(buffer).isEmpty)

        XCTAssertEqual(decoder.cumulationBuffer!.readableBytes, 5119)
        XCTAssertEqual(decoder.cumulationBuffer!.readerIndex, 0)

        // Now we're going to send in one more byte. This will cause a chunk to be passed on,
        // shrinking the held memory to 3072 bytes. However, memory will be reclaimed.
        XCTAssertTrue(try channel.writeInbound(buffer.getSlice(at: 0, length: 1)).isFull)
        XCTAssertEqual(decoder.cumulationBuffer!.readableBytes, 3072)
        XCTAssertEqual(decoder.cumulationBuffer!.readerIndex, 0)
    }
fabianfett

comment created time in 10 hours

pull request commentapple/swift-nio

Use welcoming language

@fabianfett please see my review comments. We'll need a follow-up PR unfortunately. Sorry!

fabianfett

comment created time in 11 hours

Pull request review commentapple/swift-nio

Use welcoming language

 services:    sanity:

there's a left-over "sanity"

fabianfett

comment created time in 11 hours

Pull request review commentapple/swift-nio

Use welcoming language

   -/* sanity check */+/* soundness check */

this change needs to be done in update_and_patch_sha1.sh. This file can't be manually edited because it's vendored by that script. Also add it to the top-level comment which summarises the changes.

fabianfett

comment created time in 11 hours

Pull request review commentapple/swift-nio

Fix `Codec` memory reclaim bug

 extension ByteToMessageDecoder {     public func shouldReclaimBytes(buffer: ByteBuffer) -> Bool {         // We want to reclaim in the following cases:         //-        // 1. If there is more than 2kB of memory to reclaim+        // 1. If there is at least 2kB of memory to reclaim         // 2. If the buffer is more than 50% reclaimable memory and is at least         //    1kB in size.-        if buffer.readerIndex > 2048 {+        if buffer.readerIndex >= 2048 {

what's the motivation for this change? Seems unrelated to the bugfix and obfuscates the important change?

fabianfett

comment created time in 11 hours

Pull request review commentapple/swift-nio

Fix `Codec` memory reclaim bug

 extension ByteToMessageDecoder {     public func shouldReclaimBytes(buffer: ByteBuffer) -> Bool {         // We want to reclaim in the following cases:         //-        // 1. If there is more than 2kB of memory to reclaim+        // 1. If there is at least 2kB of memory to reclaim         // 2. If the buffer is more than 50% reclaimable memory and is at least         //    1kB in size.-        if buffer.readerIndex > 2048 {+        if buffer.readerIndex >= 2048 {             return true         }-        return buffer.capacity > 1024 && (buffer.capacity - buffer.readerIndex) >= buffer.readerIndex+        return buffer.capacity >= 1024 && (buffer.capacity - buffer.readerIndex) < buffer.readerIndex
  • the first change > --> >= essentially halves the threshold. We only allocate ByteBuffers in powers of 2. So outside of slices, we should only ever see a 1024 capacity or a 2048 capacity BB, nothing in between.
  • I'd revert this change and go back to > because it's unrelated.
  • let's use .storageCapacity even though in this case it's debatable I think
fabianfett

comment created time in 11 hours

Pull request review commentapple/swift-nio

Fix `Codec` memory reclaim bug

 public final class ByteToMessageDecoderTest: XCTestCase {         _ = try channel.pipeline.addHandler(decoder).wait()          // We're going to send in 513 bytes. This will cause a chunk to be passed on, and will leave-        // a 512-byte empty region in a 513 byte buffer. This will not cause a shrink.+        // a 512-byte empty region in a byte buffer with a capacity of 1024 bytes. Since 512 empty

I think we should leave the old unit tests alone and add targeted new tests that specifically test for what was broken.

fabianfett

comment created time in 11 hours

more