CLOVIS
12/19/2024, 4:10 PMCoroutineContext
like we used to use `ThreadLocal`: to store globally-available but required information about the context, like authentication.
However, we sometimes want access to that information in non-coroutines methods. Currently, we are forced to add suspend
to these methods, even though they never suspend, to be able to access the context.
Is there a better solution?Sam
12/19/2024, 4:40 PMSam
12/19/2024, 4:41 PMSam
12/19/2024, 4:47 PMCLOVIS
12/19/2024, 4:53 PMBut isn’t it better just to make all the function’s dependencies explicit?Something like "Who is the current user?" would need to be passed to every single function in the entire app, it would make everything way more complex.
CLOVIS
12/19/2024, 4:53 PMCLOVIS
12/19/2024, 4:55 PMEssentially you make a special coroutine context element that writes its value to a thread local every time the coroutine is dispatched to a new thread. That might be your simplest solutionOh, I'm interested. I don't think it's the correct tool for "auth of the current user", but that seems interesting for things like monitoring span IDs. Thanks for the link, I'll read into it.
Daniel Pitts
12/19/2024, 6:34 PMDmitry Khalanskiy [JB]
12/19/2024, 8:04 PMclass MySession {
val user: User
val something: Something
fun foo() {
// has access to `User`
}
suspend fun bar() {
// also has access to `User`
}
}
Basically, you can hide many parameters in objects. With extension functions, methods can even be in other files. No need to explicitly pass anything if you're always in the scope.Zach Klippenstein (he/him) [MOD]
12/19/2024, 9:31 PMDmitry Khalanskiy [JB]
12/20/2024, 6:58 AMCLOVIS
12/20/2024, 8:47 AMAuth
parameter to all functions in the entire project is much worse for maintenance and readability.Daniel Pitts
12/20/2024, 2:38 PMCLOVIS
12/20/2024, 4:33 PMsuspend
, so having that as part of the coroutine context makes sense.
Recently, we discovered that actually, even the CSV exports need that information, because dates should be displayed in the user's timezone. That leaves us with multiple options:
• refactor all the CSV stuff to pass an additional data point. But that's a pain, because a lot of that DSL uses it
so if we add a second argument it greatly decreases the usability.
• refactor all the CSV stuff to be suspend
.Daniel Pitts
12/20/2024, 4:34 PMCLOVIS
12/20/2024, 4:39 PMDaniel Pitts
12/20/2024, 4:41 PMDaniel Pitts
12/20/2024, 4:42 PMDaniel Pitts
12/20/2024, 4:43 PMDaniel Pitts
12/20/2024, 4:49 PMCLOVIS
12/20/2024, 5:12 PMCode deployed to prod environment. Boom, server blows up. As the joke goes, the customer asked the bartender where the bathroom was and the bar burns to the ground.
I hear you, and I don't want to argue for global information—but that's the behavior we want. Either the server crashes because the user is unknown, or the server answers without knowing who the user is, and therefore likely accesses or edits information the user shouldn't have access to. We prefer the server crashes, and these situations are rare enough thanks to our other tests that we have high confidence they only happen in production when a user actively is trying to break the system. In which case, an HTTP 500 is near best case scenario.
Daniel Pitts
12/20/2024, 5:13 PMCLOVIS
12/20/2024, 5:14 PMThough it does tend to make you write code that is specific to your "business at the moment" logic, rather than reusable, suitably abstract code.
I hear you, but this is specifically the user ID, which is definitely not something that's going to be outdated in the future. There will always be a user.