I have data stored in ThreadLocal (such as MDC) and I need it to update it for each request.
Using the rx-netty http client I put the value as a http header but I can't find a hook where I can read this value after the control is passed into the netty thread pool and then set it on the thread local of the netty thread.
Is this possible using some API?
You can add netty's ChannelHandler using RxNetty's PipelineConfigurator(somewhat like this: https://github.com/ReactiveX/RxNetty/blob/0.4.x/rxnetty-examples/src/main/java/io/reactivex/netty/examples/tcp/cpuintensive/CPUIntensiveServer.java#L66). Then your code will be executed in Netty's eventloop.
Once you have a sample code, I can look into it, in case you need more help.
Related
We build a REST microservice with Scala 3, ZIO 2, ZIO logging and Tapir.
For context specific logging we want to use the MDC and set an attribute there which is taken from the request payload.
Is it possible to get access to the request payload in DefaultServerLog to extract the MDC attribute and then use it for ZIO logging feature MDC logging, i.e. create a LogAnnotation from the extracted attribute, so it will also be logged by all DefaultServerLog methods (doLogWhenHandled etc.). Currently it works for our own log statements, but not for those of Tapir/ZIO-HTTP.
See answer here https://softwaremill.community/t/how-to-get-access-to-the-request-payload-in-tapir-ziohttp-defaultserverlog/84/3.
Adam Warski:
"This is usually problematic as the body of the request is a stream of bytes, which is read from the socket as it arrives. That is, the request isn’t loaded into memory by default.
You can work-around this by reading the whole request into memory using serverRequest.underlying.asInstanceOf[zio.http.Request].body.asArray, extracting the required info and enriching the fiber-locals appropriately. You might also need to substitute the Request with a copy, which has the body provided as a byte array (in a “strict” form), so that the “proper” body parser doesn’t try to re-read from the network (where nothing will be available).
However, this has some downsides: the body will be parsed twice (once by your interceptor, once by the parsing that’s defined later); and it will be read into memory (which might be problematic if you don’t have a limit on the size of the body)."
I was wondering if there is some way to provide two methods to Micronaut which are guaranteed to run before and after a request was passed to the handler.
In my case, this would be to initialize some thread-local data.
I know this would also be possible to put in the handler itself but putting the same lines of code in every handler isn't really the greatest solution.
Use a filter - see the docs at https://docs.micronaut.io/latest/guide/#filters
I'm using hunchentoot session values to make my server code re-entrant. Problem is that session values are, by definition, retained during the session, i.e., from one call from the same browser to the next, whereas what I really am looking for is what amount to thread-specific re-entrancy, so that all the values disappear between calls -- I want to treat each click as a separate "from scratch" event, even if they are from the same session . Easy enough to have the driver either set to nil, or delete my session values, but I'm wondering if there's a "correct" way to do this? I don't see any thread-based analog to hunchentoot:session-value in the documentation.
Thanks in advance for any guidance you can offer.
If you want a value to be "thread specific" and at the same time to be "from scratch" on every request, that requires that every request must be dispatched in a brand new thread. This is not the case according to the Hunchentoot documentation, which says that two models are supported: a single-threaded taskmaster and a thread-per-connection taskmaster.
If your configuration is multi-threaded, then a thread-specific variable bound in a request-handling can therefore be expected to be per-connection. In a single-threaded Hunchentoot setup, it will effectively be global, tied to the request servicing thread.
A thread-based analog to hunchentoot:session-value probably doesn't exist because it would only introduce behaviors into the web app which surprisingly change if the threading model is reconfigured, or if the request pattern from the browser changes. A browser can make multiple requests using the same connection, or close the connection between requests.
To extend the request objects with custom per-request, I would look into, perhaps, subclassing from the acceptor (how to do this is described in the docs). My custom acceptor would have a custom method of the process-connection generic function which would create extended/subclasses request objects carrying the extra stuff I wanted to put into a request.
Another way would be to have some global weak hash which binds request objects as keys to additional information.
I'm trying to create a socket based communication with a server, with a Haxe client targetting CPP.
I'm looking at sys.net.Socket that looks like what I want, but every methods is synchronous! How can I wait for a server event?
I'm used to Node syntax with .on() functions, is there any equivalent here?
Thanks
There are two possible solutions for non-blocking socket access in haxe/cpp:
1) Set the socket to non-blocking
With the Socket.setBlocking method you set the blocking behavior of the socket. If set to true, which is the default, methods like socket.accept() (and likely socket.read() but I haven't personally tested it) will block until they complete.
But if you set blocking to false, those functions will throw if no data is available (you'll need to catch and move on.) So in your main loop you could access your non-blocking socket with try/catch around the read() calls.
2) Put your socket in a separate thread from your main loop
You can easily create a separate Thread for your socket communcations, so then a blocking socket is fine. In this model, your socket thread will send data back to the main thread with Thread.sendMessage(), your main loop will check via Thread.readMessage(block:Bool) whether there's new data from the socket.
Historically hxcpp and async is arduous task as there is no hxcpp main loop out of the box, so the task is virtually always deferred to a toolkit ( openfl, nme etc...)
AFAIK there is no out of the box solution, binding http://zeromq.org/ might be a straghtforward and easy task thought.
You can also defer to HTTP implemtentations boxed with your favorite toolkit.
Good luck !
Basically, I'm looking to respond to a SOAP request immediately, but also kick off further processing. What I'm seeing is that the response is not sent until the route ends. In other words:
from("cxf:bean:someEndpoint")
.to("seda:replySOAP")
.to("direct:ABCMessage");
from("seda:replySOAP")
.to("bean:soapReply?method=process").end();
from("direct:ABCMessage")
.process(new ConvertABCToNZFCY())
.to("bean:prelimNZFCYCall")
.end();
Does not generate the response until "direct:ABCMessage" has completed. I would think seda would designate asynchronous processing. I have also tried "vm:replySOAP", pointing to a separate Camel Context, and this did not help.
I have also tried multicast, to no avail:
from("cxf:bean:someEndpoint")
.multicast().parallelProcessing()
.to("seda:replySOAP")
.to("direct:ABCMessage");
What DOES work for me is wireTap, but it does not seem elegant:
from("cxf:bean:someEndpoint")
.wireTap("direct:ABCMessage")
.to("direct:replySOAP");
Must I use JMS?
Thanks!
The behavior you see is due to
.to("direct:ABCMessage");
in the routes. It is a synchronous process ie, an InOut exchange pattern. jms can be used but that may be an overkill if you are using it only to avoid wiretap. Why do you think wiretap does not seem elegant.