[swift-server-dev] Next HTTP API meeting
hatsuneyuji at icloud.com
Mon Mar 27 18:24:55 CDT 2017
> That way you are just passing an argument to a closure, not capturing as I mentioned before,
I’m not sure what you mean by capturing here, I’ll argue that you’re actually capturing a reference to the stack, as long as the stack is there the reference is always there, and for sequential operations the reference is basically there until the closure returns. Of course, the closure cannot pass the reference to a different thread that has different stack.
I’m not even against reference type at all, I just think value type has more advantage.
> 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 ?
The real question should probably be, why would you even want to do that?
First of all closure/block != multithreading.
Second for most of the web frameworks, in fact even DispatchIO, never do anything in the main thread. Main thread is usually use for the event runloop (99% the time it is either done by epoll() or kqueue(), even gcd, in fact gcd is basically high level kqueue. Most of the time all the middleware acted sequentially, so there’s no reason why you should initialize a struct in the main thread and pass it to another thread but initialize it in the worker thread instead. For example DispatchIO, you probably should initializer the struct in your DispatchIO block instead of initialize it first before even calling DispatchIO.
Even if you want to do something in background which is not sequential and move back to the main thread, one way is to block your main thread until your work is done and move back to the main thread using something live eventfd and kqueue. And TBH if you try to run something parallel for a single request, you’re going to add a lot of overheads in a number of ways for both struct/class anyway.
Let’s say if you really have to somehow pass the request by reference to different thread, you can allocate a the struct to the heap and pass by pointer, or have a dummy class container that provides ref count interface to the struct, but the reverse is not possible. Even if you nest a class into a struct you can almost never avoid heap allocation and freeing it. Which in Swift(Darwin), according to my educated guess has time complexity of O(log n). Therefore sometimes I really doubt if things like req/res that has such short life cycle is worth for trade. (That’s why a good benchmark is important I guess)
More information about the swift-server-dev