parent
74cba26b6f
commit
d489d9f38f
|
@ -35,7 +35,7 @@ public final class MakeFullRequestHandler: ChannelOutboundHandler {
|
||||||
///
|
///
|
||||||
/// `RequestResponseHandler` does support pipelining `Request`s and it will send them pipelined further down the
|
/// `RequestResponseHandler` does support pipelining `Request`s and it will send them pipelined further down the
|
||||||
/// `Channel`. Should `RequestResponseHandler` receive an error from the `Channel`, it will fail all promises meant for
|
/// `Channel`. Should `RequestResponseHandler` receive an error from the `Channel`, it will fail all promises meant for
|
||||||
/// the outstanding `Reponse`s and close the `Channel`. All requests enqueued after an error occured will be immediately
|
/// the outstanding `Response`s and close the `Channel`. All requests enqueued after an error occurred will be immediately
|
||||||
/// failed with the first error the channel received.
|
/// failed with the first error the channel received.
|
||||||
///
|
///
|
||||||
/// `RequestResponseHandler` requires that the `Response`s arrive on `Channel` in the same order as the `Request`s
|
/// `RequestResponseHandler` requires that the `Response`s arrive on `Channel` in the same order as the `Request`s
|
||||||
|
|
|
@ -529,7 +529,7 @@ public final class AtomicBox<T: AnyObject> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 2: After having gained 'ownership' of the old value, we can release the Unmanged.
|
// step 2: After having gained 'ownership' of the old value, we can release the Unmanaged.
|
||||||
let oldPtr = Unmanaged<T>.fromOpaque(UnsafeRawPointer(bitPattern: oldPtrBits)!)
|
let oldPtr = Unmanaged<T>.fromOpaque(UnsafeRawPointer(bitPattern: oldPtrBits)!)
|
||||||
return oldPtr.takeRetainedValue()
|
return oldPtr.takeRetainedValue()
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public final class Lock {
|
||||||
|
|
||||||
/// Release the lock.
|
/// Release the lock.
|
||||||
///
|
///
|
||||||
/// Whenver possible, consider using `withLock` instead of this method and
|
/// Whenever possible, consider using `withLock` instead of this method and
|
||||||
/// `lock`, to simplify lock handling.
|
/// `lock`, to simplify lock handling.
|
||||||
public func unlock() {
|
public func unlock() {
|
||||||
#if os(Windows)
|
#if os(Windows)
|
||||||
|
|
|
@ -253,7 +253,7 @@ extension ChannelCore {
|
||||||
///
|
///
|
||||||
/// Note that if the unwrap fails, this will cause a runtime trap. `ChannelCore`
|
/// Note that if the unwrap fails, this will cause a runtime trap. `ChannelCore`
|
||||||
/// implementations should be concrete about what types they support writing. If multiple
|
/// implementations should be concrete about what types they support writing. If multiple
|
||||||
/// types are supported, considere using a tagged union to store the type information like
|
/// types are supported, consider using a tagged union to store the type information like
|
||||||
/// NIO's own `IOData`, which will minimise the amount of runtime type checking.
|
/// NIO's own `IOData`, which will minimise the amount of runtime type checking.
|
||||||
///
|
///
|
||||||
/// - parameters:
|
/// - parameters:
|
||||||
|
|
|
@ -367,7 +367,7 @@ private extension B2MDBuffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A handler which turns a given `ByteToMessageDecoder` into a `ChannelInboundHandler` that can then be added to a
|
/// A handler which turns a given `ByteToMessageDecoder` into a `ChannelInboundHandler` that can then be added to a
|
||||||
/// `ChannelPipeline`.
|
/// `ChannelPipeline`.
|
||||||
///
|
///
|
||||||
/// Most importantly, `ByteToMessageHandler` handles the tricky buffer management for you and flattens out all
|
/// Most importantly, `ByteToMessageHandler` handles the tricky buffer management for you and flattens out all
|
||||||
|
@ -740,7 +740,7 @@ extension ByteToMessageHandler: RemovableChannelHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A handler which turns a given `MessageToByteEncoder` into a `ChannelOutboundHandler` that can then be added to a
|
/// A handler which turns a given `MessageToByteEncoder` into a `ChannelOutboundHandler` that can then be added to a
|
||||||
/// `ChannelPipeline`.
|
/// `ChannelPipeline`.
|
||||||
public final class MessageToByteHandler<Encoder: MessageToByteEncoder>: ChannelOutboundHandler {
|
public final class MessageToByteHandler<Encoder: MessageToByteEncoder>: ChannelOutboundHandler {
|
||||||
public typealias OutboundOut = ByteBuffer
|
public typealias OutboundOut = ByteBuffer
|
||||||
|
|
|
@ -24,7 +24,7 @@ extension DispatchQueue {
|
||||||
/// try let value = futureResult.wait()
|
/// try let value = futureResult.wait()
|
||||||
///
|
///
|
||||||
/// - parameters:
|
/// - parameters:
|
||||||
/// - eventLoop: the `EventLoop` on which to proceses the IO / task specified by `callbackMayBlock`.
|
/// - eventLoop: the `EventLoop` on which to processes the IO / task specified by `callbackMayBlock`.
|
||||||
/// - callbackMayBlock: The scheduled callback for the IO / task.
|
/// - callbackMayBlock: The scheduled callback for the IO / task.
|
||||||
/// - returns a new `EventLoopFuture<ReturnType>` with value returned by the `block` parameter.
|
/// - returns a new `EventLoopFuture<ReturnType>` with value returned by the `block` parameter.
|
||||||
@inlinable
|
@inlinable
|
||||||
|
|
|
@ -266,14 +266,14 @@ public protocol EventLoop: EventLoopGroup {
|
||||||
///
|
///
|
||||||
/// Semantically, this function is equivalent to calling `makeSucceededFuture(())`.
|
/// Semantically, this function is equivalent to calling `makeSucceededFuture(())`.
|
||||||
/// Contrary to `makeSucceededFuture`, `makeSucceededVoidFuture` is a customization point for `EventLoop`s which
|
/// Contrary to `makeSucceededFuture`, `makeSucceededVoidFuture` is a customization point for `EventLoop`s which
|
||||||
/// allows `EventLoop`s to cache a pre-succeded `Void` future to prevent superfluous allocations.
|
/// allows `EventLoop`s to cache a pre-succeeded `Void` future to prevent superfluous allocations.
|
||||||
func makeSucceededVoidFuture() -> EventLoopFuture<Void>
|
func makeSucceededVoidFuture() -> EventLoopFuture<Void>
|
||||||
|
|
||||||
/// Must crash if it is not safe to call `wait()` on an `EventLoopFuture`.
|
/// Must crash if it is not safe to call `wait()` on an `EventLoopFuture`.
|
||||||
///
|
///
|
||||||
/// This method is a debugging hook that can be used to override the behaviour of `EventLoopFuture.wait()` when called.
|
/// This method is a debugging hook that can be used to override the behaviour of `EventLoopFuture.wait()` when called.
|
||||||
/// By default this simply becomes `preconditionNotInEventLoop`, but some `EventLoop`s are capable of more exhaustive
|
/// By default this simply becomes `preconditionNotInEventLoop`, but some `EventLoop`s are capable of more exhaustive
|
||||||
/// checking and can validate that the wait is not occuring on an entire `EventLoopGroup`, or even more broadly.
|
/// checking and can validate that the wait is not occurring on an entire `EventLoopGroup`, or even more broadly.
|
||||||
///
|
///
|
||||||
/// This method should not be called by users directly, it should only be implemented by `EventLoop` implementers that
|
/// This method should not be called by users directly, it should only be implemented by `EventLoop` implementers that
|
||||||
/// need to customise the behaviour.
|
/// need to customise the behaviour.
|
||||||
|
|
|
@ -1535,7 +1535,7 @@ extension EventLoopFuture {
|
||||||
/// `EventLoopFuture` has any result. The observer callback is permitted to block.
|
/// `EventLoopFuture` has any result. The observer callback is permitted to block.
|
||||||
///
|
///
|
||||||
/// - parameters:
|
/// - parameters:
|
||||||
/// - onto: the `DispatchQueue` on which the blocking IO / task specified by `callbackMayBlock` is schedulded.
|
/// - onto: the `DispatchQueue` on which the blocking IO / task specified by `callbackMayBlock` is scheduled.
|
||||||
/// - callbackMayBlock: The callback that is called when the `EventLoopFuture` is fulfilled.
|
/// - callbackMayBlock: The callback that is called when the `EventLoopFuture` is fulfilled.
|
||||||
@inlinable
|
@inlinable
|
||||||
public func whenCompleteBlocking(onto queue: DispatchQueue, _ callbackMayBlock: @escaping (Result<Value, Error>) -> Void) {
|
public func whenCompleteBlocking(onto queue: DispatchQueue, _ callbackMayBlock: @escaping (Result<Value, Error>) -> Void) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ public struct MarkedCircularBuffer<Element>: CustomStringConvertible {
|
||||||
|
|
||||||
/// Create a new instance.
|
/// Create a new instance.
|
||||||
///
|
///
|
||||||
/// - paramaters:
|
/// - parameters:
|
||||||
/// - initialCapacity: The initial capacity of the internal storage.
|
/// - initialCapacity: The initial capacity of the internal storage.
|
||||||
@inlinable
|
@inlinable
|
||||||
public init(initialCapacity: Int) {
|
public init(initialCapacity: Int) {
|
||||||
|
|
|
@ -295,7 +295,7 @@ public final class HTTPServerUpgradeHandler: ChannelInboundHandler, RemovableCha
|
||||||
context.pipeline.removeHandler(context: context, promise: nil)
|
context.pipeline.removeHandler(context: context, promise: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the initial mandatory HTTP headers for HTTP ugprade responses.
|
/// Builds the initial mandatory HTTP headers for HTTP upgrade responses.
|
||||||
private func buildUpgradeHeaders(`protocol`: String) -> HTTPHeaders {
|
private func buildUpgradeHeaders(`protocol`: String) -> HTTPHeaders {
|
||||||
return HTTPHeaders([("connection", "upgrade"), ("upgrade", `protocol`)])
|
return HTTPHeaders([("connection", "upgrade"), ("upgrade", `protocol`)])
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ extension NIOHTTPServerRequestFull: Equatable {}
|
||||||
|
|
||||||
/// The parts of a complete HTTP response from the view of the client.
|
/// The parts of a complete HTTP response from the view of the client.
|
||||||
///
|
///
|
||||||
/// Afull HTTP response is made up of a response header encoded by `.head`
|
/// A full HTTP response is made up of a response header encoded by `.head`
|
||||||
/// and an optional `.body`.
|
/// and an optional `.body`.
|
||||||
public struct NIOHTTPClientResponseFull {
|
public struct NIOHTTPClientResponseFull {
|
||||||
public var head: HTTPResponseHead
|
public var head: HTTPResponseHead
|
||||||
|
@ -223,7 +223,7 @@ public final class NIOHTTPServerRequestAggregator: ChannelInboundHandler, Remova
|
||||||
context.fireErrorCaught(error)
|
context.fireErrorCaught(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generated a server esponse to send back
|
// Generated a server response to send back
|
||||||
if let response = serverResponse {
|
if let response = serverResponse {
|
||||||
context.write(self.wrapOutboundOut(.head(response)), promise: nil)
|
context.write(self.wrapOutboundOut(.head(response)), promise: nil)
|
||||||
context.writeAndFlush(self.wrapOutboundOut(.end(nil)), promise: nil)
|
context.writeAndFlush(self.wrapOutboundOut(.end(nil)), promise: nil)
|
||||||
|
|
|
@ -44,7 +44,7 @@ extension timespec {
|
||||||
|
|
||||||
/// Represents IO events NIO might be interested in. `SelectorEventSet` is used for two purposes:
|
/// Represents IO events NIO might be interested in. `SelectorEventSet` is used for two purposes:
|
||||||
/// 1. To express interest in a given event set and
|
/// 1. To express interest in a given event set and
|
||||||
/// 2. for notifications about an IO event set that has occured.
|
/// 2. for notifications about an IO event set that has occurred.
|
||||||
///
|
///
|
||||||
/// For example, if you were interested in reading and writing data from/to a socket and also obviously if the socket
|
/// For example, if you were interested in reading and writing data from/to a socket and also obviously if the socket
|
||||||
/// receives a connection reset, express interest with `[.read, .write, .reset]`.
|
/// receives a connection reset, express interest with `[.read, .write, .reset]`.
|
||||||
|
|
|
@ -205,7 +205,7 @@ extension Selector: _SelectorBackendProtocol {
|
||||||
|
|
||||||
var ready: Int = 0
|
var ready: Int = 0
|
||||||
|
|
||||||
// flush reregisteration of pending modifications if needed (nop in SQPOLL mode)
|
// flush reregistration of pending modifications if needed (nop in SQPOLL mode)
|
||||||
// basically this elides all reregistrations and deregistrations into a single
|
// basically this elides all reregistrations and deregistrations into a single
|
||||||
// syscall instead of one for each. Future improvement would be to also merge
|
// syscall instead of one for each. Future improvement would be to also merge
|
||||||
// the pending pollmasks (now each change will be queued, but we could also
|
// the pending pollmasks (now each change will be queued, but we could also
|
||||||
|
|
|
@ -41,7 +41,7 @@ public final class NIOWebSocketFrameAggregator: ChannelInboundHandler {
|
||||||
|
|
||||||
/// Configures a `NIOWebSocketFrameAggregator`.
|
/// Configures a `NIOWebSocketFrameAggregator`.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - minNonFinalFragmentSize: Minimum size in bytes of a fragment which is not the last fragment of a complete frame. Used to defend agains many really small payloads.
|
/// - minNonFinalFragmentSize: Minimum size in bytes of a fragment which is not the last fragment of a complete frame. Used to defend against many really small payloads.
|
||||||
/// - maxAccumulatedFrameCount: Maximum number of fragments which are allowed to result in a complete frame.
|
/// - maxAccumulatedFrameCount: Maximum number of fragments which are allowed to result in a complete frame.
|
||||||
/// - maxAccumulatedFrameSize: Maximum accumulated size in bytes of buffered fragments. It is essentially the maximum allowed size of an incoming frame after all fragments are concatenated.
|
/// - maxAccumulatedFrameSize: Maximum accumulated size in bytes of buffered fragments. It is essentially the maximum allowed size of an incoming frame after all fragments are concatenated.
|
||||||
public init(
|
public init(
|
||||||
|
|
|
@ -485,7 +485,7 @@ class EmbeddedChannelTest: XCTestCase {
|
||||||
let channel = EmbeddedChannel()
|
let channel = EmbeddedChannel()
|
||||||
let options = channel.syncOptions
|
let options = channel.syncOptions
|
||||||
XCTAssertNotNil(options)
|
XCTAssertNotNil(options)
|
||||||
// Unconditonally returns true.
|
// Unconditionally returns true.
|
||||||
XCTAssertEqual(try options?.getOption(ChannelOptions.autoRead), true)
|
XCTAssertEqual(try options?.getOption(ChannelOptions.autoRead), true)
|
||||||
// (Setting options isn't supported.)
|
// (Setting options isn't supported.)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1794,7 +1794,7 @@ class ByteBufferTest: XCTestCase {
|
||||||
XCTAssertTrue(buffer.discardReadBytes())
|
XCTAssertTrue(buffer.discardReadBytes())
|
||||||
XCTAssertEqual(0, buffer.readerIndex)
|
XCTAssertEqual(0, buffer.readerIndex)
|
||||||
XCTAssertEqual(0, buffer.writerIndex)
|
XCTAssertEqual(0, buffer.writerIndex)
|
||||||
// As we fully consumed the buffer we should only have adjusted the indices but not triggered a copy as result of CoW sematics.
|
// As we fully consumed the buffer we should only have adjusted the indices but not triggered a copy as result of CoW semantics.
|
||||||
// So we should still be able to also read the old data.
|
// So we should still be able to also read the old data.
|
||||||
buffer.moveWriterIndex(to: 1)
|
buffer.moveWriterIndex(to: 1)
|
||||||
buffer.moveReaderIndex(to: 0)
|
buffer.moveReaderIndex(to: 0)
|
||||||
|
|
|
@ -237,8 +237,8 @@ public final class ChannelTests: XCTestCase {
|
||||||
|
|
||||||
/// A frankenstein testing monster. It asserts that for `PendingStreamWritesManager` `pwm` and `EventLoopPromises` `promises`
|
/// A frankenstein testing monster. It asserts that for `PendingStreamWritesManager` `pwm` and `EventLoopPromises` `promises`
|
||||||
/// the following conditions hold:
|
/// the following conditions hold:
|
||||||
/// - The 'single write operation' is called `exepectedSingleWritabilities.count` number of times with the respective buffer lenghts in the array.
|
/// - The 'single write operation' is called `exepectedSingleWritabilities.count` number of times with the respective buffer lengths in the array.
|
||||||
/// - The 'vector write operation' is called `exepectedVectorWritabilities.count` number of times with the respective buffer lenghts in the array.
|
/// - The 'vector write operation' is called `exepectedVectorWritabilities.count` number of times with the respective buffer lengths in the array.
|
||||||
/// - after calling the write operations, the promises have the states in `promiseStates`
|
/// - after calling the write operations, the promises have the states in `promiseStates`
|
||||||
///
|
///
|
||||||
/// The write operations will all be faked and return the return values provided in `returns`.
|
/// The write operations will all be faked and return the return values provided in `returns`.
|
||||||
|
|
|
@ -1591,7 +1591,7 @@ public final class ByteToMessageDecoderTest: XCTestCase {
|
||||||
|
|
||||||
let closeFuture = channel.close() // close the channel, `removeHandlers` will be called in next EL tick.
|
let closeFuture = channel.close() // close the channel, `removeHandlers` will be called in next EL tick.
|
||||||
|
|
||||||
// user-trigger the handelr removal (the actual removal will be done on the next EL tick too)
|
// user-trigger the handler removal (the actual removal will be done on the next EL tick too)
|
||||||
let removalFuture = channel.pipeline.removeHandler(decoderHandler)
|
let removalFuture = channel.pipeline.removeHandler(decoderHandler)
|
||||||
|
|
||||||
// run the event loop, this will make `removeHandlers` run first because it was enqueued before the
|
// run the event loop, this will make `removeHandlers` run first because it was enqueued before the
|
||||||
|
|
|
@ -933,7 +933,7 @@ public final class EventLoopTest : XCTestCase {
|
||||||
if overflow {
|
if overflow {
|
||||||
XCTAssertGreaterThanOrEqual(timeAmount.nanoseconds, 0)
|
XCTAssertGreaterThanOrEqual(timeAmount.nanoseconds, 0)
|
||||||
XCTAssertGreaterThanOrEqual(deadline.uptimeNanoseconds, 0)
|
XCTAssertGreaterThanOrEqual(deadline.uptimeNanoseconds, 0)
|
||||||
// we cap at distantFuture torwards +inf
|
// we cap at distantFuture towards +inf
|
||||||
expectedValue = NIODeadline.distantFuture.uptimeNanoseconds
|
expectedValue = NIODeadline.distantFuture.uptimeNanoseconds
|
||||||
} else if partial < 0 {
|
} else if partial < 0 {
|
||||||
// we cap at 0 towards -inf
|
// we cap at 0 towards -inf
|
||||||
|
@ -967,7 +967,7 @@ public final class EventLoopTest : XCTestCase {
|
||||||
if overflow {
|
if overflow {
|
||||||
XCTAssertLessThan(timeAmount.nanoseconds, 0)
|
XCTAssertLessThan(timeAmount.nanoseconds, 0)
|
||||||
XCTAssertGreaterThanOrEqual(deadline.uptimeNanoseconds, 0)
|
XCTAssertGreaterThanOrEqual(deadline.uptimeNanoseconds, 0)
|
||||||
// we cap at distantFuture torwards +inf
|
// we cap at distantFuture towards +inf
|
||||||
expectedValue = NIODeadline.distantFuture.uptimeNanoseconds
|
expectedValue = NIODeadline.distantFuture.uptimeNanoseconds
|
||||||
} else if partial < 0 {
|
} else if partial < 0 {
|
||||||
// we cap at 0 towards -inf
|
// we cap at 0 towards -inf
|
||||||
|
|
|
@ -406,7 +406,7 @@ class SelectorTest: XCTestCase {
|
||||||
XCTAssertNoThrow(try el.submit {
|
XCTAssertNoThrow(try el.submit {
|
||||||
// EL tick 1: this is used to
|
// EL tick 1: this is used to
|
||||||
// - actually arm the timer (timerfd_settime)
|
// - actually arm the timer (timerfd_settime)
|
||||||
// - set the channel restration up
|
// - set the channel registration up
|
||||||
if numberFires.load() > 0 {
|
if numberFires.load() > 0 {
|
||||||
print("WARNING: This test hit a race and this result doesn't mean it actually worked." +
|
print("WARNING: This test hit a race and this result doesn't mean it actually worked." +
|
||||||
" This should really only ever happen in very bizarre conditions.")
|
" This should really only ever happen in very bizarre conditions.")
|
||||||
|
|
|
@ -531,7 +531,7 @@ class StreamChannelTest: XCTestCase {
|
||||||
5: --> registerForWritable (because line 4 could not write everything and flushNow returned .register)
|
5: --> registerForWritable (because line 4 could not write everything and flushNow returned .register)
|
||||||
6: --> unregisterForWritable (because line 2 wrote everything and flushNow returned .unregister)
|
6: --> unregisterForWritable (because line 2 wrote everything and flushNow returned .unregister)
|
||||||
|
|
||||||
line 6 undoes the registeration in line 5. The fix makes sure that flushNow never re-enters and therefore the
|
line 6 undoes the registration in line 5. The fix makes sure that flushNow never re-enters and therefore the
|
||||||
problem described above cannot happen anymore.
|
problem described above cannot happen anymore.
|
||||||
|
|
||||||
Our match plan is the following:
|
Our match plan is the following:
|
||||||
|
@ -605,7 +605,7 @@ class StreamChannelTest: XCTestCase {
|
||||||
context.eventLoop.scheduleTask(in: .microseconds(100)) {
|
context.eventLoop.scheduleTask(in: .microseconds(100)) {
|
||||||
switch self.state {
|
switch self.state {
|
||||||
case .writingUntilFull:
|
case .writingUntilFull:
|
||||||
// We're just enqueing another chunk.
|
// We're just enqueuing another chunk.
|
||||||
writeOneMore()
|
writeOneMore()
|
||||||
case .writeSentinel:
|
case .writeSentinel:
|
||||||
// We've seen the notification that the channel is unwritable, let's write one more byte.
|
// We've seen the notification that the channel is unwritable, let's write one more byte.
|
||||||
|
@ -804,7 +804,7 @@ class StreamChannelTest: XCTestCase {
|
||||||
// test.
|
// test.
|
||||||
XCTAssertNoThrow(try beganBigWritePromise.futureResult.wait())
|
XCTAssertNoThrow(try beganBigWritePromise.futureResult.wait())
|
||||||
|
|
||||||
// We now just set autoRead to true and let the receiver receive everything to tear everthing down.
|
// We now just set autoRead to true and let the receiver receive everything to tear everything down.
|
||||||
XCTAssertNoThrow(try receiver.setOption(ChannelOptions.autoRead, value: true).wait())
|
XCTAssertNoThrow(try receiver.setOption(ChannelOptions.autoRead, value: true).wait())
|
||||||
|
|
||||||
XCTAssertNoThrow(try finishedBigWritePromise.futureResult.wait())
|
XCTAssertNoThrow(try finishedBigWritePromise.futureResult.wait())
|
||||||
|
|
Loading…
Reference in New Issue