Commit Graph

58 Commits

Author SHA1 Message Date
George Barnett ddb7109142
Include stackdiff-ing in the debugging-allocations doc (#1384)
Motivation:

We recently grew a script to diff the output of `malloc-aggregation.d`,
we should document how this can be used when debugging allocation
regressions.

Modifications:

- Update the doc to include an example of using the script to debug an
  allocation regression
- Fix a bug in the script where before/after were mixed up
- Fix a bug in the script where usage would print '()\n' instead of '\n'

Result:

- Better info on debugging allocations

Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
2020-02-06 16:10:04 +00:00
George Barnett b4483e5c49
Avoid curried thunks (workaround SR-12115) (#1374)
Motivation:

Calling `function(otherFunction)` allocates, but
`function({ otherFunction($0) }` does not.

See: SR-12115 and SR-12116.

Modifications:

Avoid passing functions directly; pass them in new closures instead.

Result:

Fewer allocations.
2020-01-31 17:57:30 +00:00
Johannes Weiss 6bd0a9e61a
document debugging with allocation tests (#1277)
Motivation:

The tooling around the allocation counter tests is pretty opaque and
also not easy to use.

Modifications:

Document what interested folks should know.

Result:

More people will be able to debug allocations in SwiftNIO.

Co-Authored-By: Cory Benfield <lukasa@apple.com>
2019-12-02 11:05:04 +00:00
George Barnett 8aaaaab4fa Add an optimization tips document. (#1024)
Motivation:

NIO doesn't offer any tips of on how to write performant code. After
discussing with @weissi we decided it would be useful to gather and
document some useful tips and tricks.

Modifications:

Started an optimization tips document.

Result:

Easier for NIO users to write performant code.
2019-06-05 07:48:57 -07:00
Johannes Weiss 39c6b87ff8
migration guide: Info about B2MD (#949)
Motivation:

@tomerd learned the hard way that there were some subtle changes in
B2MDs around intercepting arbitrary channel events. Previously,
intercepting those was illegal but possible. In NIO 2, it's impossible.

Modifications:

add a description for what changed

Result:

easier migrations
2019-04-05 17:22:44 +01:00
Johannes Weiss 09bace11d6
minor fixes in docs (#928)
Motivation:

Some things weren't 100% clear or wrong, let's fix em.

Modifications:

fixed 'em.

Result:

better docs
2019-03-26 11:26:10 +00:00
Johannes Weiss b8368b6e09
update the documentation for NIO 2 release (#927)
Motivation:

A bunch of things change with the release of NIO 2. We should update the
documentation to reflect that.

Modifications:

- update readme
- update migration guide

Result:

up to date docs.
2019-03-26 09:11:28 +00:00
Johannes Weiss df0b0594ec
CircBuffer: docs: add that indices are no longer Strideable (#914)
Motivation:

CircularBuffer indices are no longer `Strideable`, document this.

Modifications:

added to the public api changes doc

Result:

better docs
2019-03-23 15:05:12 +00:00
Johannes Weiss a8fbcf080b
EmbeddedChannel: remove mystery bools (#917)
Motivation:

EmbeddedChannel.finish/writeInbound/writeOutbound returned some mystery
bools. I always had to check the code to remember what they actually
meaned.

Whilst this is technically a breaking change, I couldn't find any users
of the return values on Github that are using the convergence releases.

Modifications:

Replace them by enums giving you all the information.

Result:

- fixes #916
- clearer APIs
2019-03-22 12:34:16 +00:00
Johannes Weiss 4ffa858ce6
make HTTPMethod.hasRequestBody internal (#908)
* make HTTPMethod.hasRequestBody internal

Motivation:

HTTPMethod.hasRequestBody was unnecessarily public.

Modifications:

make it internal

Result:

fixes #151

* Update public-api-changes-NIO1-to-NIO2.md
2019-03-19 13:02:34 +00:00
Cory Benfield 8adf87baa6
Update migration guide with now-converging repos. (#905)
Motivation:

swift-nio-http2 and swift-nio-transport-services are now converging.

Modifications:

Updated the migration guide.

Result:

Docs will be up to date.
2019-03-15 15:03:01 +00:00
Johannes Weiss 08ae2308be
migration guide: swift-nio-ssl has converged (#901)
Motivation:

We should have accurate information in our guides.

Modifications:

Note that swift-nio-ssl has converged.

Result:

correct info
2019-03-13 17:02:04 +00:00
Johannes Weiss 785f7620f2
fix wrong URL for swift-nio-extras 2019-03-08 19:30:39 +00:00
Johannes Weiss edda576522
update migration guide: convergence (#891)
Motivation:

Mention convergence in migration guide.

Modifications:

tell people about the correct dependencies in the migration guide.

Result:

happier users.
2019-03-08 19:30:02 +00:00
Johannes Weiss 36a52e1ea3
remove WebSocketFrameDecoder inline error handling (#885)
Motivation:

Follows on from the work done in #528 for #527: we have moved the the
default error handling out of WebSocketFrameDecoder, but had to leave
the code there for backward compatibility reasons. We can remove that
code now.

Modifications:

Removed automatic error handling code in WebSocketFrameDecoder.

Result:

- fixes #534
2019-03-08 19:11:39 +00:00
Johannes Weiss acb37911c0
remove overloading from scheduleRepeatedTask (#886)
Motivation:

scheduleRepeatedTask had two overloads: for synchronous and asynchronous
tasks. They however had the same name so they were pretty much
impossible to use.

Modifications:

rename the asynchronous version of scheduleRepeatedTask to
scheduleRepeatedAsyncTask

Result:

- NIO easier to use
- fixes #882
2019-03-08 15:37:58 +00:00
Johannes Weiss 22e6cd3c67
HTTP/1 headers simplification & cleanup (#857)
Motivation:

The HTTP/1 headers were quite complicated, CoW-boxed and exposed their
guts (being a ByteBuffer). In Swift 5 this is no longer necessary
because of native UTF-8 Strings.

Modifications:

- make headers simply `[(String, String)]`
- remove `HTTPHeaderIndex`, `HTTPListHeaderIterator`, etc

Result:

- simpler and more performant code
2019-03-06 18:11:40 +00:00
Johannes Weiss eb524c72ad
improve and simplify MessageToByteEncoder (#868)
Motivation:

MessageToByteEncoder was a protocol that similar to ByteToMessageDecoder
was pretty hard to hold correctly (override some methods but not
others). This PR brings MessageToByteEncoder more in line with the new
ByteToMessageDecoder.

Modifications:

- refactor `MessageToByteEncoder`
- introduce `MessageToByteHandler`, similar to `ByteToMessageHandler`

Result:

- better API, more similar to ByteToMessageDecoder
- fixes #864
2019-03-04 19:19:53 +00:00
Johannes Weiss 7528ecd374
convert NIOWebSocketUpgradeError from enum to struct (#866)
Motivation:

We need to fix #577 sometime soon and in preparation of that we'll
change convert NIOWebSocketUpgradeError from enum to struct.

Modifications:

convert NIOWebSocketUpgradeError from enum to struct

Result:

- NIOWebSocketUpgradeError can be adjusted without SemVer major breaking
  changes
- fixes #839
2019-03-04 14:19:18 +00:00
Johannes Weiss baa3390b15
remove HTTPResponseCompressor (#865)
Motivation:

We're not happy with HTTPResponseCompressor's API and it needs to
incubate a little more, hence moving to
[`swift-nio-extras`](https://github.com/apple/swift-nio-extras).

Modifications:

- removed HTTPResponseDecoder
- removed the zlib dependency

Result:

- no more HTTPResponseDecoder
2019-03-04 13:52:30 +00:00
Cory Benfield 9c07f89ec7 Allow delaying HTTP upgrade decisions. (#844)
Motivation:

While the HTTPServerUpgrader and WebSocketUpgrader allowed users to take
their time when reconfiguring the pipeline after they decided to upgrade,
users had to synchronously decide if they wanted to upgrade. This is a bit
inconvenient.

A particular limitation here is that some routes may want to upgrade
only if the upgrading user is authenticated. Checking authentication
credentials is almost always an I/O operation, and so cannot safely be done
on the event loop. Our original design made this impossible.

Modifications:

- Changed the shouldUpgrade callback to return a Future.
- Passed the shouldUpgrade callback the Channel that is upgrading, in
    no small part so that it has an EventLoop it can create Futures
    on.
- Rewrote the upgrader to handle this new state.

Result:

Users can delay decisions about when to upgrade.
2019-03-01 18:24:59 +00:00
Johannes Weiss da52b59ced
fix/improve some NIO1APIShims (#856)
Motivation:

We had wrong/suboptimal API shims.

Modifications:

improve them

Result:

easier porting from NIO1 to NIO2
2019-02-28 16:16:17 +00:00
Johannes Weiss 37a64b74c6
NIO 1 to 2 migration guide (#847)
Motivation:

The NIO 1 to 2 migration is not too bad if you know a few tricks. So we
should list them in a migration guide.

Modifications:

add first cut of migration guide

Result:

happier users
2019-02-28 11:21:48 +00:00
Johannes Weiss 14327af193 don't leak pthread_keys (#157)
Motivation:

Previously we leaked `pthread_key`s as we only ever called
`pthread_key_create` but never `pthread_key_delete`. This patch fixes
that.

Modifications:

- made `ThreadSpecificVariable` a class (so we get lifecycle management
  through ARC)
- instead of just storing the value, store `Box<(ThreadSpecificVariable<T>, T)>`
  so we can control the lifecycle of the `ThreadSpecificVariable` as
  needed

Result:

We don't leak `pthread_key`s anymore.
2019-02-26 14:57:47 +00:00
Johannes Weiss a41280919e
rename ctx to context (#842)
Motivation:

`ctx` was always an abbreviation was 'context` and in Swift we don't
really use abbreviations, so let's fix it.

Modifications:

- rename all instances of `ctx` to `context`

Result:

- fixes #483
2019-02-25 18:20:22 +00:00
Johannes Weiss 862533d089
B2MD: Don't deliver data after error (#837)
Motivation:

B2MD should never call any of the decode functions after the user has
thrown an error.

Modifications:

introduce an error state and make sure we don't call out if in error
state

Result:

B2MD more correct
2019-02-25 17:18:11 +00:00
Johannes Weiss afbab95f27 address #186: rename BlockingIOThreadPool to NIOThreadPool (#838)
Motivation:

The thread pool implementation can be used for many things not just
blocking IO.

Modifications:

rename BlockingIOThreadPool to NIOThreadPool

Result:

fixes #186
2019-02-25 16:51:47 +00:00
Johannes Weiss ff31b3135d
improve B2MD EOF handling (#831)
Motivation:

Previously B2MDs didn't really have defined semantics regarding EOFs and
we didn't tell them if there was an EOF. Also `decodeLast` was optional
and all that was bad.

Modifications:

- require `decodeLast`
- add a `seenEOF: Bool` parameter to `decodeLast` which tells the
  decoder if an EOF has been seen

Result:

- clearer semantics
- more information
2019-02-21 14:14:50 +00:00
Johannes Weiss 46ffd630de
ChannelPipeline: addHandler and removeHandler instead of add/remove (#817)
Motivation:

- `ChannelPipeline.add(name:handler:...)` had a strange order of arguments
- `remove(handler:)` and `remove(ctx:)` both remove `ChannelHandler`s
  but they read like they remove different things

So let's just fix the argument order and name them `addHandler` and
`removeHandler` making clear what they do.

Modifications:

- rename all `ChannelPipeline.add(name:handler:...)`s to `ChannelPipeline.addHandler(_:name:...)`
- rename all `ChannelPipeline.remove(...)`s to `ChannelPipeline.removeHandler(...)`

Result:

more readable and consistent code
2019-02-21 11:46:54 +00:00
Johannes Weiss 5143f0bc17
opaque indices for (Marked)CircularBuffer (#826)
Motivation:

Opaque indices are a good idea for collections, (Marked)CircularBuffer
should use those too.

Modifications:

Cheapest possible implementation for opaque indices, could be much
improved. This is the cheapest possible implementation for opaque
indices and this could be much improved later, see #682 but the
improvements won't be SemVer major :).

Result:

first stab at #682
2019-02-19 18:46:01 +00:00
Johannes Weiss bf3b87cb4e
simplify ChannelOptions (#828)
Motivation:

ChannelOptions used a too complicated mechanism for what they are.

Modifications:

- change the ChannelOptions to a much simpler mechanism
- rename the generic parameters from T to Option

Result:

code easier to read and understand
2019-02-19 18:31:26 +00:00
Johannes Weiss 3d3cc6d685
rename FileHandle to NIOFileHandle (#818)
Motivation:

Collisions with Foundation and other standard libraries is painful.

Modifications:

- rename `FileHandle` to `NIOFileHandle`
- rename `Thread` to `NIOThread` (only exposed in docs)

Result:

fewer collisions
2019-02-19 16:52:00 +00:00
Johannes Weiss 877f0ebc12
require ChannelOptions to be Equatable (#823)
Motivation:

ChannelOptions should've always been Equatable and so far we've hacked
around them not being Equatable when we wanted to compare them.

Modifications:

make all ChannelOptions Equtable

Result:

- ChannelOption comparison actually works
- fixes #598
- make more ChannelOptions stuff inlinable to not regress allocations
2019-02-19 12:30:26 +00:00
Johannes Weiss 03aa0bd43e
rename Channel._unsafe to Channel._channelCore (#820)
Motivation:

_unsafe is non-descriptive

Modifications:

- rename Channel._unsafe to Channel._channelCore

Result:

clearer API
2019-02-14 14:14:11 +00:00
Nathan Harris 9e73705fd4 Update ELF parameter labels to be more Swifty (#809)
Motivation:

As part of NIO2 - much work has been done to round out the API of EventLoopFuture. This finishes existing public API parameters to be more in line with Swift API guidelines.

Modifications:

Methods in EventLoopFuture that had `eventLoop` as a parameter label have been changed to `on`

Results:

EventLoopFuture public API is more "Swifty" with calls such as `future.hop(to: eventLoop)` rather than `future.hopTo(eventLoop: eventLoop)`
2019-02-12 21:40:23 +01:00
Johannes Weiss 1198931823 ByteBuffer: rename set(<type>:, ...) to set<Type>(...) (#812)
Motivation:

ByteBuffer methods like `set(string:)` never felt very Swift-like and
also didn't look the same as their counterparts like `getString(...)`.

Modifications:

- rename all `ByteBuffer.set/write(<type>:,...)` methods to
  `ByteBuffer.set/write<Type>(...)`
- polyfill the old spellings in `_NIO1APIShims`

Result:

code more Swift-like
2019-02-12 11:11:45 +00:00
Johannes Weiss d938264fcb
better ChannelHandler removal API (#767)
Motivation:

If ChannelHandler removal worked correctly, it was often either by
accident or by intricate knowledge about the implementation of the
ChannelHandler that is to be removed. Especially when it comes to
re-entrancy it mostly didn't work correctly.

Modifications:

- introduce a `RemovableChannelHandler` API
- raise allocation limit per HTTP connection by 1
  (https://bugs.swift.org/browse/SR-9905)

Result:

Make things work by contruction rather than accident
2019-02-12 11:27:48 +01:00
Nathan Harris 06fb45d07e Rename `ELF.andAll(_:eventLoop:)` to `andAllSucceed(_🔛)` and add `ELF.andAllComplete` (#803)
Motiviation:

After adding `ELF.whenAllComplete` the concept of "fail fast" and "fail slow" for reducing an array of future results together was introduced.

This commit adds that concepts with the `andAll* methods that act as simple completion notifications.

Modifications:

Rename `EventLoopFuture.andAll(_:eventLoop:)` to `andAllSucceed(_🔛)` to denote its "fail fast" nature, and to match Swift API guidelines.

Add new `EventLoopFuture.andAllComplete(_🔛)` for a "fail slow" companion.

Shift implementation of `whenAllComplete(_🔛)` to be usable without unnecessary allocations in `andAllComplete`

Result:

EventLoopFuture now has two methods for "flattening" arrays of EventLoopFuture into a single notification ELF
2019-02-06 09:16:48 +00:00
Nathan Harris caf9a3d8da standardize `ELF.cascade*` collection of methods (#802)
Motivation:

The `ELF.cascade` methods have a parameter label `promise` that does not match Swift API Guidelines, and a way to cascade just successes is not available - while for failures there is.

Modifications:

`ELF.cascade*` methods that already exist have had their `promise` label renamed to `to`, and a new `ELF.cascadeSuccess` method has been added.

Result:

EventLoopFuture now has the cascade methods `ELF.cascade(to:)`, `ELF.cascadeFailure(to:)`, and `ELF.cascadeSuccess(to:)`
2019-02-05 09:01:48 +00:00
Tanner 0154604408 rename HTTPProtocolUpgrader to HTTPServerProtocolUpgrader (#750)
* rename HTTPProtocolUpgrader to HTTPServerProtocolUpgrader
2019-01-31 11:36:55 +00:00
Johannes Weiss 2ad1e21512 CircularBuffer.init: rename initialRingCapacity to initialCapacity
Motivation:

initialRingCapacity is not a great name, initialCapacity is much better

Modifications:

rename CircularBuffer(initialRingCapacity:) to initialCapacity

Result:

more consistent code
2019-01-29 12:29:04 +00:00
Johannes Weiss f3294dd803 rename ELF.mapIfError to ELF.recover (#777)
Motivation:

The name `mapIfError` implied that you can transform the error value but
really that's never what it did. Instead, it allowed you to recover
from a failure.

Modifications:

- rename `mapIfError` to `recover`

Result:

cleaner method names
2019-01-24 17:09:13 +00:00
Johannes Weiss c4ff795dda
remove ELP.succeed/fail's labels (#776)
Motivation:

EventLoopPromise.succeed/fail has extraneous labels that don't add
anything but noise.

Modifications:

remove extraneous labels

Result:

less noise in the code
2019-01-24 16:42:53 +00:00
Johannes Weiss 3e7d6a7bfd rename ELF.then to ELF.flatMap (#760)
Motivation:

ELF's API should be as close as possible to the new Result's API.
Therefore, we should rename `then` to `flatMap`

Modifications:

- renamed `then` to `flatMap`
- renamed `thenIfError` to `flatMapError`
- renamed ELF's generic parameter from `T` to `Value`

Result:

- more like Result
- fixes #688
2019-01-21 16:41:04 +00:00
Johannes Weiss f32f283dd4
declare public API (#673)
Motivation:

SemVer requires us to declare a public API, we should do so for NIO 2.

Modifications:

declare our public API.

Result:

more transparency into our versioning policy.
2019-01-19 14:17:38 +00:00
Johannes Weiss 684cad331c EventLoopFuture: use Result type (#734)
Motivation:

Now that the stdlib has introduced the Result type, we can use it in the
implementation (and the whenComplete) function of EventLoopFuture

Modifications:

- replace EventLoopValue with Result
- make whenComplete provide the Result

Result:

use the new shiny stuff
2019-01-05 08:08:47 +00:00
Johannes Weiss 531745d71a
remove ContiguousCollection (#709)
Motivation:

ContiguousCollection is no longer necessary because Sequence gained
withContiguousStorageIfAvailable.

Modifications:

Removed ContiguousCollection and switch to withContiguousStorageIfAvailable.

Result:

less code
2018-12-18 09:20:37 +00:00
Cory Benfield 15be5243ef Improve ByteBuffer String APIs (#696)
Motivation:

ByteBuffer has pretty good string writing APIs, but they're imperfect.
In particular, the methods in ByteBuffer-aux both return optional Int,
which is strange as they cannot fail. We also only have support for writing
strings in UTF-8.

Modifications:

- ByteBuffer.set(string:at:) and ByteBuffer.write(string:) now both
     return `Int`, and their return value has been made discardable.
- NIOFoundationCompat has been expanded with two new methods for writing
     strings to ByteBuffers in various encodings using Foundation's
     encoding support: ByteBuffer.set(string:encoding:at:) and
     ByteBuffer.write(string:encoding:).
- NIOFoundationCompat has also been expanded with a companion to the
     already existing ByteBuffer.getString(at:length:encoding), namely
     ByteBuffer.readString(length:encoding:).
- New error enum for reporting failures to encode.

Result:

Easier to work with strings in a wider variety of cases with
ByteBuffer

Resolves #253.
2018-12-14 17:25:13 +00:00
Bas Broek 6772f13c29 Change unnecessary functions to variables (#695)
* Change unnecessary functions to variables

Motivation:

The changed functions do not have any side effects and therefore better convey intent when being a simple computed variable.

Modifications:

Changes:

- `func markedElementIndex() -> Int?` to `var markedElementIndex: Int?`
- `func markedElement() -> E?` to `var markedElement: E?`
- `func hasMark() -> Bool` to `var hasMark: Bool`

Result:

- improved code quality
2018-12-11 17:50:58 +00:00
Cory Benfield f3f6e09ba2
Make WebSocketOpcode a struct. (#694)
Motivation:

WebSocketOpcode was made an enumeration to make it possible to cleanly
switch over the values in switch statements. However, this unfortunately
made it possible to construct contradictory values of WebSocketOpcode,
such as .unknownNonControl(0x1) (which should be spelled .text), or
.unknownControl(0xFF) (which is simply invalid).

This patch removes the ability to construct invalid values of
WebSocketOpcode by turning it into a struct and using static lets for known
values. While we're here it cleans some other stuff up.

Modifications:

- Made WebSocketOpcode a struct
- Added several static lets for easy access and to reduce code churn
- Used synthesised Equatable conformance
- Added synthesised Hashable conformance
- Added CustomStringConvertible conformance to better represent known values
- Added CaseIterable conformance to provide entire range of valid values.

Result:

WebSocketOpcode will be a better-behaved type with more guarantees and
fewer places to trap and explode.

Resolves #617.
2018-12-11 11:56:10 +00:00