PeterAdams-A/async-http-client 0
HTTP client library built on SwiftNIO
The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)
The Swift language implementation of gRPC.
Swift Server Working Group (SSWG)
A Logging API for Swift
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
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
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
comment created time in 4 hours
push eventapple/swift-nio
commit sha 6b41c18bf6418f7b1a6c00493dba1e80f54e1bb3
Fix Codec memory reclaim bug (#1729)
push time in 5 hours
PR merged apple/swift-nio
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.
pr closed time in 5 hours
push eventgrpc/grpc-swift
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).
push time in 5 hours
PR merged grpc/grpc-swift
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).
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
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
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
comment created time in 6 hours
PR opened apple/swift-nio
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.
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
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.
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?
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.
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?
comment created time in 9 hours
push eventapple/swift-nio
commit sha 0260fc32cf5030ba547ac9c23c0913d82088f8db
Replace unwelcoming language in sha1 (#1731)
push time in 9 hours
PR merged apple/swift-nio
Follow up to #1728
Modifications:
- In
update_and_patch_sha1.sh
we replace occurrences ofsanity check
withsoundness check
Result:
c_nio_sha1.h
and c_nio_sha1.c
don't have manual changes anymore.
pr closed time in 9 hours
PR opened apple/swift-nio
Follow up to #1728
Modifications:
- In
update_and_patch_sha1.sh
we replace occurrences ofsanity check
withsoundness check
Result:
c_nio_sha1.h
and c_nio_sha1.c
don't have manual changes anymore.
pr created time in 9 hours
issue openedapple/swift-nio
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.
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.
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.
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.
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)
}
comment created time in 10 hours
pull request commentapple/swift-nio
@fabianfett please see my review comments. We'll need a follow-up PR unfortunately. Sorry!
comment created time in 11 hours
Pull request review commentapple/swift-nio
services: sanity:
there's a left-over "sanity"
comment created time in 11 hours
Pull request review commentapple/swift-nio
-/* 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.
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?
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 a1024
capacity or a2048
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
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.
comment created time in 11 hours