I have a vertex app that exists as an application ...
# getting-started
a
I have a vertex app that exists as an application that will handle multiple requests at a time (typical stuff). I'd like to hold a global variable per request that can be accessed anywhere in the code, but not stored on the request context that vertex provides since that's not available everywhere in the code. Is there any way to do this?
I mean the code itself can figure out how to not mix multiple requests together, right? So it should be possible? Like if I can get an id for the current "thread", I can use it as a key in a general store that vertx provides or perhaps a redis instance...
c
I don’t know much about Vert.X, but I believe it’s non-blocking by nature which means a single request isn’t necessarily served by a single thread, so mechanisms like
ThreadLocal
probably won’t work. I doubt you’ll be able to set a global property and expect it to work, but a quick search looks like RequestContext could be the properly-scoped container that you could manage that data in
a
Request context would be, but I don't want to have to pass that context to functions so they can be passed to functions so they can be passed to a function that needs data within. There's got to be a better way.
e
if you were using vertx-lang-kotlin-coroutines and coroutines all the way down, then CopyableThreadContextElement would work. but that's basically just getting the compiler to do the context passing for you, but less safely than doing it explicitly since the code doesn't statically know that it's in a context with that element
j
I've spent a lot of time in the past, trying to figure out the answer to this question 😄 I'm afraid there is no reasonable way to do it, without rewriting the vert.x internals.
a
Shoot, that's not the answer I wanted 😞 Did you come up with some other approach to your other problem? What is bothering me is that with Sentry, I can call
Sentry.setTag(...)
at the beginning of the request and it seems to successfully hold that tag across the lifetime of a request as I want to do here. This means either 1. They have a solution, or 2. I am misunderstanding sentry and I am using it wrong. Yikes.
e
unfortunately, I'm pretty sure you're using it wrong and that's not safe with Vert.x (same with coroutines)
for coroutines, there's a specific SentryContext that can be installed which fixes it
j
It might work only if Sentry uses that tag within the same handler call (and unsets it, otherwise it might leak to other requests).
e
I don't see any integration like that for Vert.x though
c
Yeah, I dont think Sentry is doing anything special with Vertx, it’s just a Java SDK. So it’s not natively aware of anything Vertx is doing with requests, threads, etc.
j
We have in the end settled with passing the context in every function that needs it. It makes one keep the function hierarchy concise and not create lasagna-code 🙂
a
So in my case, db related functions and functions that call db related functions (aka the whole app) would all be passing the request context around. Yikes.
e
a "global" (even a request local one) passed behind the scenes through multiple calls is a much bigger yikes, IMO
a
Here's what I was trying to do: We have a DB trigger that for audit purposes will save db changes to a table. This is agnostic to the app. We also have a transaction log that is managed by the app saving data about every request. My goal is to connect the 2 by putting the application log ID onto the db logs that the trigger creates. This allows me to link a db change to an application request. Exiting! I have everything figured out on the SQL side, how to pass of a variable that the trigger will use, safely etc. But, this means that any place we are talking to the db in the app, we would have to have access to the request context. I mention this in case anyone would have an idea of how to approach this in a better way. I suspect that the act of tying parts of the code that are agnostic to the request lifecycle , with a request lifecycle, is my fatal flaw?
d
I don't know vert.x but I solved a similar problem by using context receivers. That way you don't have to pass the global parameter around, yet it's still pretty explicit because every method that needs it (even the callers of such methods) state that they need that parameter/context.