Network.framework: A modern alternative to sockets
developer.apple.com
developer.apple.com
From what I can gather from watching this so far is, it just sounds like a layer you can optionally choose to use on-top of sockets that manages things like: TLS, multiple networks (4G/3G/Wi-Fi), DNS resolving, proxies, etc for you so you don't need to write it all yourself from scratch every time.
Maybe I'm wrong about that, or maybe none of this is actually as hard as it sounds in practice. But this seems like it might be atleast some what useful.
That's what you get from things like deprecating OpenGL and replacing it with a non-multiplatform alternative: bad reputation. They should ask Microsoft if it's easy to get rid of if once you have it.
BSD sockets isn't a bastion of extensible interface design, it basically amounts to one giant ioctl() in every operating system. Darwin has weird escape hatches built into it (AF_SYSTEM) much like Linux netlink, and protocol parameter documentation is strewn across 5+ man pages each documenting a different set of magic value combinations for non-portably controlling some part of the stack. TCP_USER_TIMEOUT? That's one of many, many Linux socket options, but it's part of our precious so-portable socket interface we must maintain forever!
OS X chooses to bury its system call interface too, it's always been considered a private detail of the C library. I see no reason why socket() and friends couldn't similarly be forgotten. If some clean 21st century redesign of an ancient API has knock-on effects for the structure of code in open source projects across the ecosystem, that's probably a good thing in the long run. Progress never happens by hugging the past, especially when that past is ugly and filled with horrors
Try not to look at this as "hey, MacOS is breaking precious UNIX", but more as "hey look, why can't Bonjour+multipath TCP be a one liner on Linux too?"
The real knife in the back was when they forked for Metal instead of adopting Vulkan. I've not used Vulkan in anger yet(just a couple toy demos) but everything I saw pointed to it solving all the major issues people have with OpenGL. Now there's another N+1 APIs, shader language and graphics pipeline that you need to support if you're building a graphical application and not leveraging Unity/UE4/etc.
[1] https://github.com/KhronosGroup/MoltenVK/blob/master/Docs/Mo...
I think people would be ok with Apple dropping OpenGL if they supported Vulkan, but their motivation and desire to lock people into Apple-only APIs is so obvious and transparent... Why would you support it?
At least Microsoft works with third parties and acknowledges the existence of some standards. Apple are always like "Here is the Apple way. I mean, the way. Because there is only Apple. Apple is the whole world and nothing else exists."
* Vulkan was a recommended API on android N+, which has ~35% device install (from first % stats that came up on google). However, the CDD doesn't require Vulkan to be present. * Linux is it up to the distribution to include it, and it isn't currently required by any standard open source package. If your card isn't AMD or Nvidia, you do not have an option for vulkan support AFAIK. * Windows it is something installed by the video card driver as part of their game support and not available across all cards * Mac/iOS it is built on top of Metal and available as a free third party library for your app bundles
I'm sure people would prefer Apple lead the pack and embrace a new standard before the rest of the industry, but it doesn't really buy them anything with their Metal investment to be first adopter, and it is very Anti-Apple to want to cede that sort of control. Especially when nobody else is doing it.
Not really by any standard. It is about as good as other APIs of a similar level of abstraction (certainly no fair comparison with X11), and crucially it is widely supported. OS X's support for OpenGL is very poor (they are behind on standards by more than half a decade, despite shipping hardware that supports all the new stuff) because Apple has been hostile to it, just as they are not interested in enabling Vulkan in any way (though that hasn't stopped the industry from routing around Apple's tremendous narcissism).
OpenGL will continue to be available for a long time. But the idea that you would want to develop new applications for it… well, the mismatch between the OpenGL API and the way modern GPUs work is just too big. You can paper over the small problems with a bunch of small changes but at this point I think it’s extremely fair to say, “you want OpenGL, be prepared to bring your own implementation.” This is a good thing, we are getting OpenGL implementations on top of e.g. Vulkan, Metal, DX12 that are going to be more consistent and easy to target than all the differences between vendor OpenGL implementations.
It’s extra work for developers but I believe it’s better for long term platform health. It just makes more sense for OpenGL to be a fat library, and it makes things easier if you can target one version of the library instead of five. Again, this is basically what happened with OpenSSL.
Compared to what? Direct3D? I don't think it is fair or reasonable to compare OpenGL to libraries which exist on a completely different level of abstraction. The last straw for OpenSSL was in the implementation, not the API design, so I don't really understand the comparison.
The only saving grace is that OpenGL is kinda sorts cross-platform. If your platform provides drivers that are worth a shit, which has been a big question.
Well, I guess I would just say I disagree. I am relatively new to graphics programming, and the right thing was the first thing I found, every time. The most confusing part reading people warning people not to use compatibility contexts at the beginning of articles from the transitional period.
> The only saving grace is that OpenGL is kinda sorts cross-platform. If your platform provides drivers that are worth a shit, which has been a big question.
This bit I largely agree with, but even if it were the worst it's ever been (and it's not), it would still be better than implementing your application twice or thrice. I have been lucky enough to be on Mesa (primarily) for the last eight or so years, and driver quality has been of minimal concern to me.
Similar, but the differences matter. kqueue is readyness-oriented. It tells you that the driver is ready to queue more writes. But you still need to call fsync and friends to confirm that your data has actually been written out. There's no non-blocking fsync. Servers like Redis run an extra thread just to call fsync; and eat all the performance problems that entails.
In contrast, IOCP is completion-oriented. There's no need for any blocking fsync calls in order to find out when data has been written. Its way more granular - the OS can reorder writes. And it doesn't suffer from fsync's awful non-local error handling problems.
Honestly I'm surprised there's no equivalent for linux / BSD. (I mean, we have AIO but its really not good enough). IOCP is a fantastic API for high performance databases and servers. It enables faster and simpler server code. We should collectively get on it.
You can build a proactor pattern on top of a reactor pattern, but that implementation needs to provide quite a bit - more coordination of pending memory/state and probably needing back pressure support (which I never really understood if Microsoft supplied or if you had to track that yourself).
I know Microsoft used to have several IOCP-related patents; I believe I remember one for event scheduling for multi-threaded locality (preferring to dispatch a completion to the same thread that made the original request).
You still need FlushFileBuffers even with IOCP if files are opened in buffered mode (which is the default). While you will know when a write was completed, an explicit flush is still needed to make sure it’s written through. So it’s pretty much exactly the same case as with fsync(). Alternatively, you can use the write-through mode, but that kills performance like that, especially with a random write pattern.
IOCP is basically a better/cleaner abstracted epoll() that also doubles as a manager of a worker thread pool.
The framework looks really good. They mention at the end of the video that some of the things might not be very well polished but I'm sure it's all going to get there in the end.
That would have been my guess as well, but looking at the slides it appears to actually have a separate "user space networking" path (p105-108 in the PDF).
So not entirely sure it's built on top, at least not API-wise. Of course, there are sockets underneath in the OS.
On macOS, I believe they're still using the traditional in-kernel transport stack for everything. They want to move to user-space for macOS though, this is why Network Kernel Extensions (NKEs) are deprecated (which started last year). I wouldn't be surprised if macOS uses the user-space stack starting next year and NKEs are fully gone (this also corresponds with 32-bit processes being gone)
AHA, so this is why I had to hit the Google cache for that documentation. I wanted to write an NKE as a side-project but they just blackholed all the docs, this is the first I'm seeing about deprecation.
https://developer.apple.com/videos/play/wwdc2017/707/ https://developer.apple.com/videos/play/wwdc2017/709
Also, the 30% less overhead is underwhelming. I would have expected much better improvement than that. That being said, if their measurement includes the encryption layer then the I/O benefit may be overshadowed by the encryption overhead.
Still, pretty cool stuff to make publicly available.
Which is to say, you're saying "detrimental impact on performance" and yet this seems to be a significant win over BSD sockets.
It was UDP.
> Which is to say, you're saying "detrimental impact on performance" and yet this seems to be a significant win over BSD sockets.
The point I was trying to drive home is that, while 30% overhead reduction compared to BSD socket is nothing to laugh at, a fully user-space UDP/TCP network stack combined with memory-mapped buffer sharing usually gives performance improvement measured in the "x" and not in the "%".
Now, there is not much in terms of experiment protocol in their material so its very hard to tell. You mention uncompressed video so they could be sending humongous frames, which I doubt as no one ever would send raw frames over the network (that would be several MB per frame for a 720p front camera). But if that is the case then the data copy operation becomes the predominant bottleneck and getting rid of one may justify the improvement. But that is not a realistic scenario.
The more realistic scenario is that they sent compressed delta-frames across the network (H264 or HEIF), which would then considerably reduce the transferred payload size. In that scenario, data copy is not the predominant overhead anymore and 30% overhead reduction is underwhelming, telling me that they still are calling expensive operations like syscalls/uIPC on the critical data path.
[0] https://devstreaming-cdn.apple.com/videos/wwdc/2017/707h2gkb...
I am not doubting they have some sort of user-space TCP implementation. I am trying to understand how much of TCP they moved out of the kernel. From what I can gather they still have enough of it in the kernel such that the related syscall/uIPC overhead does not allow more than the 30% performance improvement announced.
My second reaction being: "Oh, well, I'll just make it a web app instead of a native app."
edit Rephrased the last sentence.
2. Not everything is a webapp or http. You may absolutely need to use the raw network without any encapsulation. This posibility must simply not die. Its true that most people will not need to use this apis and will use a http webapp.
On the API itself. I think it is a really good idea to make a new generic tcp/udp library. With everything we use today included, and as a first class citizen from the first minute of the design. The particular API they present looks good and it is very well thought out. Mostly integrates async tcp/upd/tls seemless and supports changing interfaces on the fly. This alone is a big improvement. Does this while still providing raw access to the out/input net queues. You can even access the lowlevel details and parameters if you want or need to.
However this is not the first modern network API. QT (qt network) has a good network layer for one. There are simpler alternatives: libuv, libevent etc. This are more speciallized and dont handle all that Network.framework offers.
I agree that removing sockets would break large chunks of the ecosystem. On the other hand, after OpenGL's removal, it's not clear to me that Apple cares anymore about anything outside of Cocoa.
> 2. Not everything is a webapp or http. You may absolutely need to use the raw network without any encapsulation. This posibility must simply not die. Its true that most people will not need to use this apis and will use a http webapp.
Of course. Nearly 100% of my code is not webapp/http. Which is why I'm annoyed when I see (or in this case, fear) cross-platform APIs disappear.
> On the API itself. I think it is a really good idea to make a new generic tcp/udp library. [...]
I have no problem with a new, better, API. But I would certainly be more enthusiastic if any effort was presented to make it cross-platform and, hopefully, open-source and/or standardized.
They opensourced libdispatch[1] and ported it to linux, so there's hope they might do the same with Network.framework. It would be time consuming, but it shouldn't be hard for someone in the opensource community to write a linux / BSD implementation of this stuff on top of posix sockets & libdispatch.
I suspect the reason they didn't opensource it is that it looks like it was designed mostly with phone apps in mind, not servers. And thats a shame - it looks like it would be a great addition to the swift server story, especially given it does user-space networking out of the box. I still prefer swift's ergonomics over rust for application development, and this would help immensely. (Rust is steadily closing that gap though, what with native wasm support and async/await on their way.)
Implementing this (similar functionality) API on Linux on top of libuv/libevent and gnutls + multipath tcp shouldnt be much work. Well, maybe multipath tcp is problematic, I dont know details there.
[0] "Supposed to" is my opinion on OpenGL. At the time it was the only cross-platform graphics API, and with Valve pushing a DirectX to OpenGL converter and building all their games with OpenGL support, we were finally going to get to a standard interface to graphics hardware. I guess that ship has sailed now. At least there will be abstractions that compile to the various platforms.
You can keep using sockets if that is your thing.
True.
> You can keep using sockets if that is your thing.
For the moment, yes. However, as you know, earlier this week, Apple has officially deprecated OpenGL and OpenCL, a few years after introducing a competing (and admittedly suprerior) API. It is my understanding that Apple has not attempted to get this replacement API standardized, nor to offer it on any other platform. While it's hard to deduce from such a small sample, this precedent does suggest that the days of sockets are numbered.
This would make the life of some of my colleagues quite more complicated, and it would, in time, simply get rid of the macOS version of a number of existing cross-platform applications whose authors have neither the time nor the energy to rewrite the network layer.
Apple has enough business with developers that care about macOS experience, not plain ports from other platforms.
When I buy a computer with a specific OS, I want the experience provided by the OS APIs.
However, I am a developer. When I write an application, I only have so much time to spend on ports. Anything that requires me to have different designs for different platforms is bad for me. So, in the ideal case, we'll end up with a few high-level cross-platform abstractions (which may actually share Network.framework's API, for all I know) on top of networking, and everybody will remain happy. In the worst case, we'll end up with bits of duct tape, or simply with fewer macOS apps.
Also, even as a macOS user, most of the applications I use daily are cross-platform: Firefox, Thunderbird, VSCode, my various compilers & interpreters & debuggers, VLC, Gitter, Open Office, Terminal, games, etc. In fact, looking at my recent applications, the only single-platform applications I seem to be using are Keychain, SimpleComic, Instruments (the only one in the list to particularly integrate with the OS), Notes, Calendar. I sometimes use Pages and Keynote, both of which have nice UX, but the niceties don't strike me as particularly OS-integrated.
As I mentioned above, everything that makes it harder for developers to add macOS to their list of targets encourages them to not port their app to my current OS of choice. I'm thinking of, well, many in the list above, including games.
This is, I imagine, part of the reason why so many developers left single-platform development for web development. At least, that's my reaction.
Spot on. You even gave an example of this: VSCode. If Microsoft is doing it, you can bet loads of other people are.
Well, what are the niceties you see? I'd generally say that Pages and Keynote's integration with macOS is one of their strengths.
I chose the platform I use for a reason. Why should I be ok with apps that undermine that by taking the lowest common denominator approach to porting?
Chrome
Firefox
Hipchat
Vim
Git
So, not one single-platform tool in the bunch. I'd even go so far to say that, aside from my terminal emulator and app install tool, I don't use any single-platform tools in my day to day job.
> Why should I be ok with apps that undermine that by taking the lowest common denominator approach to porting?
Because they're, in many cases, as good if not better than the native-only alternatives?
Do you want Safari to be the only web browser on macOS, Quicktime to be the only video player, etc? Not saying that it will happen, but with the disappearance of OpenGL and if sockets eventually disappear, too, it will become more difficult for independent web browsers (e.g. Firefox, Servo), independent video players (e.g. VLC, MPlayer), etc. to create or maintain a macOS version.
At some point it may happen, but there’s simply no writing on the wall for it right now.
But I'll remain at least a bit worried, if you don't mind :)
Doesn’t mean they couldn’t have changed course, but I’m sure it was a factor.
Yeah. This is exactly what people thought in the early 2000s of IE6. It was the de facto 'standard' web browser. Whole enterprises were built on the assumption that no other browser matters.
But the world around changed. IE6 became obsolete. Then insecure. People kept running it to use the old apps that would not work on modern browsers. But eventually, IE6 had to be buried.
Thousands of apps containing billions of lines of code had to be re-written at an astronomical cost. Just because, for a short while, we once thought specializing on one platform was a sustainable long-term strategy.
Websites written for IE6 can still be used today with minor changes. The problem is activex and other crappy plugin technologies. If people had just targeted Win32, those apps would still be working today - but probably still end up requiring a rewrite because of modern security requirements.
On the other hand, it is easier to install Chrome on your machine, if you need a Chrome-locked webapp, than to install macOS on the same machine. In fact, the only platform on which you cannot install a Chromium-based Chrome is iOS, and that's a political choice by Apple.
edit Rephrased entirely.
I'm ambivalent about platform-specific solutions but I welcome any attempt to obsolete socket() and select()/poll() and friends. I absolutely loathe that API.
I skimmed the video and it really looks like sockets++: once you have the connection the rest is up to you. It doesn't seem to break anything on the wire. Unless you're referring to compilation - but we can assume that Libuv will soon abstract this platform away (just like it does with Windows IOCP).
So, while Apple is not going anywhere, whichever technologies you're using to build your iOS apps might.
If it's deprecated on macOS, it's going to be around for a lot longer. They can certainly make things hellish for users trying to install your kext, but the APIs will still be there.
Taken to the extreme, this makes no sense. What's the point of even having different operating systems if there's only one acceptable API? Do you guys think operating systems can never be allowed to introduce a feature and corresponding API call?
The POSIX API is often called Berkley Sockets because a vendor, BSD, released their API and it was widely adopted. ANSI C cobbled together existing C compilers into a standard, and POSIX itself was trying to tame a huge mess of Unices.
And even if the standards don't fully converge, you have standard libraries to plaster over the differences. Everyone has to contend with weird Windows path conventions and such, to the point where it's hardly even notable.
We now live in a time where it's much easier to share code, thanks to technologies such as Qt, Java, .Net + Xamarin, game engines, web applications, etc. Any sign that we could be returning to the bad old days is, well, not a good sign.
Now, I agree with you that the real bad sign here is not Network.framework, it's the deprecation of OpenGL/OpenCL, apparently without any attempt to go towards the open standard Vulkan. Now, Apple introduces a new technology designed to replace an existing API, and people's built-in pattern-matching (including mine) see it as a sign that Apple might be testing the water before removing a well-known, cross-platform API. That's the kind of behavior that the previous King of the Hill kept using during the bad old days, and Apple seems to have borrowed more than one page from that time's Microsoft, so why not this one?
[1] https://developer.apple.com/documentation/network/implementi...
Also, personally, I suspect this is another hint of an upcoming transition to ARM64-based Macs. They will only implement these new Apple-specific APIs, not the legacy/deprecated ones like OpenGL.
I'd also say there's very little reason as a typical developer to write socket code; just use a library provided by the platform or your language. When's the last time you used the raw sockets API?
This is an established term for IP-level sockets, of SOCK_RAW protocol type. Probably not what you meant.
And related to sockets, yeah when those OSes do provide some kind of POSIX like compatibility, and even then some advanced configurations are only possible via the OS specific APIs.
[1] https://images.apple.com/media/us/osx/2012/docs/OSX_for_UNIX...
* Open source UNIX foundation
** Support for multiple CPU and GPU cores via Grand Central Dispatch and OpenCL
* Comprehensive UNIX user environment
** Standards-based graphics built on PDF (Quartz), OpenGL, and H.264 (QuickTime)
Your 2011/2012 document gives less assurance towards any future POSIX compliance.This is really there for Swift/Obj-C developers who want to use sockets but have something easier to grok than BSD sockets or NSStream, especially when you need to deal with TLS (Secure Transport, as simplified as it is, is still more difficult to use than saying "open this socket with TLS please"). BSD sockets are also ugly as sin to use in Swift because of rampant use of pointers (it's C, after all) - so there's that too.
What this means is that while BSD sockets will continue to work for the foreseeable future, native cocoa apps and cross platform apps with specialized ports will have a leg up in performance, stability, and safety over dumb ports using BSD sockets.
In other words, you’re free to keep using BSD sockets at your own detriment.
We'll see in 4 years.
It’s an Apple library for an Apple platform, to make things easier for people using Swift/Objective-C.
Some people care about that.
Just because it’s not an open standard t shouldn’t be discussed?
From what I can tell, Network.framework is a different API still talking TCP, UDP and so forth underneath.
I was asking whether Network.framework sockets can be used via functions like “dispatch_read”, analogously to how you can plug BSD sockets into POSIX I/O functions as file descriptors.
To clarify, the whole networking stack isn't userspace. They still have the classical BSD networking stack. I think the userspace networking stack is used automatically by system libraries like URLSessions and this new Network.framework library. They introduced their userspace networking stack during last year's WWDC: https://developer.apple.com/videos/play/wwdc2017/707
It's an interesting read. I'm not finished with the video, so I don't know if this is the way that Apple went.