[swift-server-dev] Next HTTP API meeting

Helge Heß me at helgehess.eu
Thu Mar 30 04:31:02 CDT 2017


On 30. Mar 2017, at 04:40, Brent Royal-Gordon <brent at architechies.com> wrote:
>> On Mar 29, 2017, at 10:53 AM, Helge Heß via swift-server-dev <swift-server-dev at swift.org> wrote:
>> 
>> The other thing is that async (not NIO) essentially requires @escaping closures while sync stuff often doesn’t. @escaping is a pretty big big overhead.
> 
> If you're making the async call and then immediately blocking, then `withoutActuallyEscaping(_:do:)` will allow you to pass a non-escaping closure to the async call. The documentation even includes an example like that.

Ah, new 3.1 goodness 👍, haven’t seen this one yet. Here is the link:

  https://developer.apple.com/reference/swift/2827967-withoutactuallyescaping?changes=latest_minor

(It still says that it creates a copy of the closure, but I guess a cheaper, stack allocated one?).

And the example given:

    func perform(_ f: () -> Void, simultaneouslyWith g: () -> Void,
                 on queue: DispatchQueue) 
    {
      withoutActuallyEscaping(f) { escapableF in
        withoutActuallyEscaping(g) { escapableG in
          queue.async(escapableF)
          queue.async(escapableG)
          queue.sync(flags: .barrier) {}
        }
      }
    }

The specific API we have been discussing is reading from the HTTP request stream, Johannes’:

  public typealias HTTPBodyHandler = (HTTPBodyChunk) -> Void
  public enum HTTPBodyProcessing {
    case discardBody
    case processBody(handler: HTTPBodyHandler)
  }

  serve { (req, res) in
    res.writeResponse(status: .ok, transferEncoding: .chunked)
    return .processBody { chunk in
      switch chunk {
        case .chunk(let data): res.writeBody(data: data)
        case .end:             res.done()
        default:               res.abort()
      }
    }
  }

That example could actually be implemented by a synchronous server (like as a mod_swift handler). To avoid the escaping overhead the `withoutActuallyEscaping` may be helpful.
But it ties the consumer to a pretty specific request handling model. While the underlying framework can be synchronous, the user is still forced to the event driven model. I think the whole idea in Go-like-aproaches is to avoid exactly that.

hh



More information about the swift-server-dev mailing list