-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using a concurrent DispatchQueue #92
Comments
Ah, indeed that's the behavior you're getting as described. Using a concurrent queue with an XPCServer will cause concurrent handlers to run if the requests are from different clients, but not concurrently from the same client. I have ideas of how to change this behavior so calls from the same client are (mostly) concurrent, but will need to give it some thought. |
It seems to me that SecureXPC provides:
Is it feasible to add a completion callback API to the server handlers? Sounds like it would be a lot of work, and only useful for pre-Monterey :( |
The server API is exclusively closure-based. However, your issue with it is that the closures are never called concurrently for requests from the same client. If they were called concurrently, that would meet your needs. Is that a correct understanding? |
Yes indeed, concurrently-called handlers would be great. It would also fit nicely with the client / server / routes metaphor, at least in my mind. I have to be honest — to date I assumed that the handlers I'd written using For what it's worth, when I said there's no closure-based API on the server side, I meant in the sense that you currently provide both Since the route sync/async status has no bearing on whether it's actually called sync/async'ly, I'm not certain how relevant the above paragraph is now though. Sorry if I seem to have an odd perspective on all this! My app is massively Promises-based, including the previous incarnation of my helper code (it all predates Swift's new Concurrency). So when I converted my old helper to leverage SecureXPC it was all with a promises / completion-handler mentality, in which virtually everything is running asynchronously. |
Try out this branch and let me know if this behaves the way you're expecting.
They are (well the degree of concurrency is up to the Swift runtime to decide), it's the synchronous ones that were not. This difference in behavior was not intentional.
I'm not 100% sure what you have in mind, but I think there is actually what you describe, but may not be for your use case. There are in fact six versions of the |
I'm trying it now, thanks! My first attempt is returning:
...after my handler completes. Just checking through my testing code to see if I'm doing something silly. |
For this branch, should I be setting (Although I've tried it with and without, and still get the error) |
🎉 Horray, it works! (would you believe I was forgetting to update the helper — I'm so used to the awesome self-updating mechanism provided by This is exactly what I was hoping for. I've added two dummy routes which call these handlers: static func testHandlerOne(withMsg msg: String) throws -> String {
print("starting handler one")
sleep(4)
return "Handler one responds with \(msg)"
}
static func testHandlerTwo(withMsg msg: String) throws -> String {
print("starting handler two")
let process = Process()
process.launchPath = "/bin/sleep"
process.arguments = ["4"]
process.launch()
process.waitUntilExit()
return "Handler two responds with \(msg)"
} I can call any combination of these multiple times, rapid-fire, and after four seconds the responses from both all come back rapid-fire as expected. This is fantastic, thanks again. Tomorrow I'll begin porting this into my app; it may take me some time as I have some handlers which leverage Swift's |
Great to hear it's working for you. The branch I pointed you at was a proof of concept, it's possible the exact API which I release won't match - but it will enable the same concurrent behavior you're currently getting. At most you'd need to set one or two additional properties (if they're not the default ones) for the server. There's a good chance I'm going to enable both unrestricted concurrency (what that branch currently always does) as well as concurrency with serial execution per client (what the released version currently for synchronous handlers, but not |
@jeff-h Would you be up for trying out the server-concurrency branch and letting me know if it works properly for you (I hope so as I wrote some automated tests) and what you think of the API design. There's no longer an ability to set a I'm not sure which branch I'm going to go with. This one offers more customization, but I've yet to decide if it's worth the additional (framework internal) complexity. |
Trying it now. |
Using this new branch my app builds and runs seamlessly without any code changes, and appears to function as expected 👍 Regarding the new functionality, I'm vastly under-qualified to offer an opinion on any of it lol but nonetheless...
|
Thanks for the feedback. I've gone with the former approach along with improved documentation. This has now been incorporated into 0.7.0. |
I've set my server's target queue like so:
...but calling my test handler multiple times from the client still indicates them running serially.
I noticed the following in the
xpc_connection_set_target_queue
documentation:Is what I'm trying to do the right approach?
The text was updated successfully, but these errors were encountered: