Plan for NIO 2 and Swift 5

As I'm sure you are aware, the first Swift 5 branches will be cut soon and needless to say SwiftNIO wants to be able to make full use of the new features/improvements upcoming in Swift 5 (for example native UTF8 Strings). On top that, SwiftNIO already accumulated a number of issues/PRs that can only be addressed with a new major SwiftNIO 2.0.0 release.
Our plan is to therefore release SwiftNIO 2.0 together with Swift 5.0. NIO 2 will require Swift 5 and will be a breaking release. Don't expect everything to break when you need to migrate from NIO 1 to NIO 2 but there will be likely a number of things that can hopefully be fixed mostly through search & replace. We will maintain a list of changes with strategies to resolve this.

Here an outline of that process:

  • soon after the first Swift 5 branches are cut, SwiftNIO's master branch will become the development branch for SwiftNIO 2.0.0, ie. it will require Swift 5 straight away and there will be breaking changes. Together with this we will release one last SwiftNIO 1.x minor release (which will likely become SwiftNIO 1.12.0)
  • up until at least the next Swift release after Swift 5.0 (Swift 5.1 presumably) SwiftNIO 1 will remain officially supported and we will release bug fix releases (likely 1.12.x) as required. There will be a branch (likely to be called nio-1.12 which will move forward with all the patch releases to be released)
  • for security fixes we will likely have a much more relaxed policy so we will try to keep SwiftNIO 1 as secure as possible for the foreseeable future
  • we will have CI support for both Swift 5.0 on master and Swift 4.{0,1,2} for the last NIO 1 train branch (likely nio-1.12)

Both Swift and SwiftNIO are evolving and therefore we feel we best serve our users by focussing on leveraging the best Swift can give us rather than spending our time trying to support Swift 4 and 5 in one release. SwiftNIO focusses on performance and it has already become apparent that sometimes new Swift versions allow us to write a certain piece of SwiftNIO functionality in an entirely different (and incompatible) way to leverage better performance. HTTPHeaders for example are implemented in more complex way than is warranted because in Swift 4.0 and 4.1 that allowed us to gain better performance. Native UTF8 Strings in Swift 5 will allow us to get much better performance with much simpler code and quite likely we will want to use features that Swift 4 just doesn't have and will never get.

On top of that I would assume that most SwiftNIO adopters will also cut a new major release for Swift 5 and the plan I outlined above should give everybody the chance to support SwiftNIO 2 & Swift 5 before they get released. And even if you can't do that just yet, we will continue to support SwiftNIO 1 for some time.

For swift-nio-{ssl,http2,transport-services,extras,examples} we plan to go with a similar plan of cutting a new major version for Swift 5.

I hope that works for everybody, please let us know what you think and if you have any questions or suggestions!

:rocket:

32 Likes

This sounds absolutely fine for Kitura. Thanks @johannesweiss!

1 Like

Too be honest - unless there are more radical API changes - I'd prefer to keep the version and #if swift(>=) the Swift 5 changes. Yes, this is a little ugly sometimes, but not that much (especially if you place the different versions in different files/compat directories).

I'm aware that this is probably not a very popular opinion though :slight_smile:

Great news! Vapor should follow suit soon after SwiftNIO with development on the next major version.

Will you be tagging pre-releases (i.e., 2.0.0-alpha.1), or will we need to depend on .branch("master")?

1 Like

We are on board with this plan, thanks for the update @johannesweiss

1 Like

The #ifs aren't powerful enough for that. For example to conditionally add an attribute (like @inlinable) you'd need to copy the whole function body and everything it calls. Then it'd basically become two code bases in one repo which becomes unmaintainable. Also we want to delete deprecated stuff and make use of new features in Package.swift etc.

1 Like

At the very beginning I'd probably recommend to depend on master, then in later stages I'd be open to have pre-releases. We very much would like input from our community here.

If you're going to require Swift 5 for NIO, can you also update the Package manifest to use the latest tools version? At the very least, it will allow you to drop the zlib and openssl support dependencies.

Yes, we'll be // swift-tools-version: 5.0 from day 1 and we'll be super happy to drop the support packages :slight_smile:

4 Likes

We had some trouble using tip of branch dependencies during Vapor 3's development. IIRC, there are some features of SPM that become unavailable. That might not be a problem anymore with Swift 5's SPM though, so I think we can address tagging pre-releases if/when it becomes an issue.

paging @Aciid

The limitation is that all branch-based dependencies should be reached via other branch-based dependencies.

Not allowed:

A depends on B @ 1.0.0
B depends on NIO @ master

Allowed:

A depends on B @ develop
B depends on NIO @ master

This limitation can be worked around but packages with branch-based dependencies shouldn’t publish releases in the first place. The workaround is:

A depends on B @ 1.0.0
A depends on NIO @ master
B depends on NIO @ master

2 Likes

What's the plan for Xcode support? Will certain commits be synced to certain toolchain builds, or will you just work off the latest? Who knows what Apple's Xcode release plan is for Swift 5, but I wouldn't expect a version with official support until the official Swift 5 release in the spring.

Also, I should get my logging PR up at some point.

I think the plan right now is to work from the latest 'Swift 5.0 Development' toolchains that will (hopefully) be available on swift.org/download as soon as the swift-5.0-branch will be cut.
Time will tell how stable those toolchains will be and if we need to maintain some form of guidance on what exact toolchain to use. I'd say let's deal with this issue when it becomes one. The extra benefit of working with the latest snapshots is that we can give early feedback to the Swift compiler developers.

In Xcode you'd need to have whatever is the latest and then select the custom toolchain in Xcode -> Toolchains.

That's about what I expected. I just wish there was a way to have a project open with a toolchain automatically, like you can with rustup.

1 Like

That would make a great SwiftPM proposal I think. Maybe it could even advise Xcode (through the generated xcodeproj) what toolchain to use?

I think that last part is the issue: Xcode has no way of setting a toolchain on per project level, AFAIK. That would require integration on Xcode's side for SPM to take advantage. I'm not sure how SPM support would work on its own, as SPM is part of the toolchain.

paging @Aciid again :slight_smile:

You can add a user-defined build settings at the project level with the settings name "TOOLCHAINS". The value should be the bundle identifier (can be obtained from Info.plist) of an installed toolchain.

5 Likes

We have released SwiftNIO 1.12.0 which in all likelihood will be the last minor release in the NIO 1 series. It's well possible that there'll be NIO 1.12.x releases for bug fixes.
Immediate consequences:

  • master will become Swift 5-only any time now (probably tonight)
  • later today we should get CI (including PRs) for the nio-1.12 train branch
2 Likes