[swift-server-dev] Next HTTP API meeting
Yan Ka Chiu
hatsuneyuji at icloud.com
Thu Mar 30 15:46:20 CDT 2017
Okay I'm going to assume the definition of blocking io means the socket itself does not set to non blocking here in this discussion.
If my assumption is correct, who not just have a global event loop to listen to sockets, and when a heap that use the fileDescriptor as key that stores a stack of context.
So the flow will be:
Each time when the file descriptor triggered we simply ask an idle worker thread to read front the socket, process the payload if necessary, and push contexts to the stack if necessary. Finally, empty the stack when the connection is gone (So the stack is reusable just like the heap).
This way can can actually stores value types referenced to the stack. Because of the uniqueness of file descriptor and the uniqueness of the event loop, the heap iterator and the stack are always accessed by a thread a time (maybe not the things in the stack tho) the whole implementation of the stream can be pretty much lock free. Nevertheless, since if stacks are implemented as linked list we can even reuse a lot of the nodes so it will also minimize heap allocations.
Michael
Sent from my iPad
> On Mar 30, 2017, at 8:06 AM, Johannes Weiß via swift-server-dev <swift-server-dev at swift.org> wrote:
>
> Hi Helge,
>
>> On 30 Mar 2017, at 15:43, Helge Heß via swift-server-dev <swift-server-dev at swift.org> wrote:
>>
>> On 30 Mar 2017, at 16:28, Johannes Weiß <johannesweiss at apple.com> wrote:
>>> I meant trivial as in easy to create once, not in easy to create the code. A function
>>>
>>> func synchronise<T>(_ func: ((T) -> Void) -> Void) -> T
>>>
>>> which is easy to write might help though.
>>
>> Well, yes, this is easy exactly the other way around :-) I’ve done this:
>>
>> https://github.com/NozeIO/Noze.io/blob/master/Sources/fs/Directory.swift#L12
>>
>> public func readdir(_ path: String, cb: @escaping ( [ String ]? ) -> Void) {
>> module.Q.evalAsync(readdirSync, path, cb)
>> }
>> public func readdirSync(_ path: String) -> [ String ]? { .. }
>>
>> I’d claim the reverse, it is often easier to go from sync to async. Dispatching on a GCD queue is trivial :-)
>
> well, both aren't too hard but I believe DispatchQueues aren't a great place to do blocking IO on. There's a limited number of threads (that you don't directly control) and you wouldn't want to sacrifice one of those per request, right? But I agree it's possible easily too.
>
>
>>> AFAIK, libmill and friends all use setjmp/longjmp which is unsupported in Swift anyway and might/will break
>>
>> OK, lets assume that the Go approach won’t be supported (or pure synchronous IO like in Apache). This still leaves us with alternative async I/O frameworks. E.g. I’d potentially like to use libuv in Noze.io and replace GCD channels with that. Or do you want to standardise this effort on GCD?
>
> can you expand what would make that incompatible with what I proposed?
>
> --
> Johannes
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev
More information about the swift-server-dev
mailing list