[swift-server-dev] Next HTTP API meeting

Helge Heß me at helgehess.eu
Tue Apr 4 12:43:54 CDT 2017

On 4. Apr 2017, at 15:31, Chris Bailey <BAILEYC at uk.ibm.com> wrote:
> Is there anything preventing us from creating streams that support both sync and async APIs? NSStream provide both sync APIs, and the ability to provide async APIs by scheduling the stream on to a RunLoop.

I guess the only thing speaking against it is that more options are not necessarily better (rose-gold MacBookPro? bah!). If there is a sync API, reuse potential certainly increases.

Something I’ve been thinking of doing in an own framework in which I want to support both styles is a pair of protocols:

  protocol SyncFetcher {
    func fetch(sql: String, cb: ( Record ) -> Void)
    func async() -> AsyncFetcher
  extension SyncFetcher {
    func sync()  -> SyncFetcher { return self }
  protocol AsyncFetcher {
    func fetch(sql: String, @escaping cb: ( Record ) -> Void)
    func async() -> AsyncFetcher // returns self
    func sync() -> SyncFetcher
  extension ASyncFetcher {
    func async()  -> AsyncFetcher { return self }

The user code looks exactly the same

  fetcher.fetch { record in

but he could decide between the imps by calling

  fetcher.async.fetch { …

etc. The object implementing the protocol would know which style it supports (or both) and resort to the other style via either barriers (async->sync) or by using a worker queue (sync->async).

The advantage is that sync stacks can avoid the escape-overhead and that the usage would be type safe (e.g. the sync setup would guarantee that you can’t pass out closure you received for later processing - which is neat for middleware `next` callbacks). That makes sense even in async frameworks in scenarios where the user knows (and can get compiler guarantee) that he is not escaping closures.

> We could take a similar approach allowing you to assign a serial DispatchQueue.

What do you mean by that?

> Admittedly that wouldn't help build a libuv based solution - but at some point we will need to be opinionated, and saying that Dispatch is the concurrency/async framework shouldn't be too contentious. 

I have some concerns about that, but maybe solely rooted in missing knowledge. Does GCD really scale well enough? I mean it was invented for client applications, that is to handle some queues, a few threads, and maybe some hundreds or thousands of async blocks. In a server application that would go up a lot …

This is a place where (stream) protocols may be neat (make (Dispatch)Queue a protocol instead of a concrete implementation, etc). Then you could hook in other approaches, like uv, etc.

I don’t care too much, but I think it may be worth a consideration to keep this open. Along the lines of Johannes' API, which can be even implemented in Apache ...


More information about the swift-server-dev mailing list