[swift-server-dev] Next HTTP API meeting

Helge Heß me at helgehess.eu
Mon Mar 27 17:58:05 CDT 2017


On 27 Mar 2017, at 23:38, Sergo Beruashvili <sergo_bero at icloud.com> wrote:
>> This has the assumption that data must be fed using closures, that certainly doesn’t have to be the case and should probably be the concern of the web framework.
> 
> Not necessarily, some requests might use closures, some not, but would be bad to constrain this just because of using structs

No one constrains this: I think that such considerations are just too low level for this discussion.

If a higher web framework needs reference semantics:

  class IncomingMessage: MessageHeadWrapper {
    let parsedHeader : HTTPParser.MessageHead
  }

  protocol MessageHeadWrapper { // can be shared by all or not
    let parsedHeader : HTTPParser.MessageHead
  }
  protocol MessageHeadWrapper { // relay
    subscript(key: string) { return parsedHeader[key] }
    .. etc ..
  }

I guess there are other ways to accomplish that, just one way to do it.


> Escaping closures can be convenient (unless you go crazy w/ the ref cycles), but do have a non-negligible performance impact! Kinda like the most expensive way to do callbacks ...
>> 
>> BTW: the async IO you talk about is mostly done on the body stream (hence chunked I/O and trailing headers …). The stream obviously has to be a reference type.
> 
> I am not talking about incoming request. But about any data that you have to fetch from extrernal sources to create a response.

Yeah, me too. The body streams are passed around as a reference. You want full connection parking, which is nice, but not necessary to stream content asynchronously.


On 27 Mar 2017, at 23:16, Michael Chiu via swift-server-dev <swift-server-dev at swift.org> wrote:
> 
> I tried the following code and it build and run. 
> 
> struct EmptyStruct {}
> func test(closure: @escaping (inout EmptyStruct) -> () ) {
>  var foo = EmptyStruct()
>  closure(&foo)
> }

Yeah, this is nice and Sergo was way too general in his statements. But this is just a hook, it doesn’t address Sergo’s example.


On 27 Mar 2017, at 23:31, Sergo Beruashvili via swift-server-dev <swift-server-dev at swift.org> wrote:
> How would you create a closure for this function, that does something in background queue, then moves to main queue and changes a property of original struct? Can you provide a sample ?

I think this should work. The middleware signature is actually this:

  ( inout Request, inout Response, next ) -> Void

Your implementation would do:

  app.use { req, res, next in
    background.queue.do {
      .. work, takes a long time, ...
      main.queue.do {
        next() 
      }
    }
  }

Now you are probably thinking, how can this work, the req value must be gone? Well, no, because the next closure is provided by the calling context and can actually capture the original value.
Didn’t try, but looks doable :-) A Node-style framework would probably want to wrap though. But there are other approaches but Node’s.

hh



More information about the swift-server-dev mailing list