Is it possible to serialize handling of a specific...
# ktor
b
Is it possible to serialize handling of a specific route? For example, I have
user/{userId}
and want to make sure all requests for a given
userId
are handled in the order they were received. I've tried doing this in the route implement, but because there are multiple threads calling it there's still wiggle room as to the order in which they're handled: I know the network is already a variable, but I'm trying to get as close as possible to handling them in the order in which they were received. I looked at doing this in a feature, but even then the request is already dispatched to a worker thread so they've already been parallelized, is there a lower level hook? Or maybe this whole endeavor is misguided?
s
are you trying to, like, impose some kind of total ordering of server responses? like if request A comes in before request B, but B takes less time to respond to, you still want A to be responded to first?
b
In this case, yes, because request B will be dependent on state that could have changed as a result of request A
I know ensuring ordering when a network is involved can be a bit of a fool's errand, but in this case the requests are coming from the same entity, so there's at least some network "consistency" and I'm at least trying to avoid introducing any further reordering
But this serialization is only within a given 'scope', so for a given
userId
, in this example
s
so, synchronous handling of specific asynchronous requests… I guess there’s a couple ways of doing it, but wouldn’t it be easier to just hold a lock on any sort of transactional state? (keyed by
userId
, probably)
b
Well, the requests are currently parallelized at a very low level, so they get re-ordered just within ktor's handling itself.
I tried what you described, but found that it didn't help as things got reordered before I even have a chance to sync on the userId
s
that’s rough, I wish I had an answer for you
I’m not sure what a good way of doing it is if the requests are, effectively, being dispatched out of order by ktor
b
Yeah, I guess it's a bit of a weird case. It's a port of a prior API that's xmpp-based, so trying to replicate some behaviors the best I can. Eventually we'll hopefully get to a point where we're not so reliant on the order of requests, but that'll take a few iterations.
I do find it a bit weird that setting
connectionGroupSize
,
workerGroupSize
, and
callGroupSize
all to
1
in the
embeddedServer
config still results in parallelization, but from what I can see in the code, ktor still lets
Jetty
create its own threadpool, so that may be where the multi-threading is coming in
Though when I debug I see the request is on a
<http://Dispatchers.IO|Dispatchers.IO>
thread
t
I have never used ktor in practice, but sometimes I find it useful to add more tooling rather than bending existing one into doing something they might be meant to. in your case, it sounds like you could replace network call with a message, queue system easily supports ordering. depending on your need you can go heavy weight (kafka, there things are ordered by key, and if you use
userid
as key for your message, message A is processed before message B) or more lightweight. just be sure ordering is guaranteed by the system you choose
b
Thanks @thanksforallthefish, I think it's a fair point. One thing I'm considering is trying a websocket connection in ktor, as I think that may have better semantics around order preservation