Is HTTPBuilder in Grails thread safe?
If HTTPBuilder is wired to a Grails service class, will it be safe to use? Or should it be instantiated on every invocation?
There doesn't seem to be any concrete answer as to whether HTTPBuilder in Grails is thread safe or not. I'm inclined to go with non thread safe due to the lack of documentation regarding that particular aspect, but I'd like a definitive answer.
The code seem to indicate it should be ok to handle multiple requests from multiple threads so long as they will go through to the same URL with the same context (headers, authenticators etc.).
Do you mean groovyx.net.http.HTTPBuilder? It has several fields that are modified by calling methods, and there's no synchronization or locking, and no use of thread-safe collections or other classes, so no, it's very much non-thread-safe. Most builders are similarly stateful and should be assumed to not be thread-safe.
Related
We are currently using an older version of Quarkus, so I would want to understand the impact and consider if we should upgrade to the latest version.
I learnt that since version 2.2 Quarkus will run method on I/O thread or Worker thread depending on the method return type (https://quarkus.io/blog/resteasy-reactive-smart-dispatch/#new-world-new-rules), meaning blocking/sync method not returning Uni/Multi/CompletionStage will be automatically offloaded to a worker thread so that it will not block the I/O thread.
In our current implementation with the older version of Quarkus and RESTEasy Reactive (I think it is 1.12.2), for all the methods not returning Uni/Multi/CompletionStage I believe they will get called on the I/O thread because we are not using #Blocking on them. These methods include actions such as calling external APIs, accessing databases and accessing files, etc, so I assume it should be our responsibility to do these actions in a non-blocking/async manner by using reactive libraries, otherwise they will block the I/O thread (Given that not all these methods I mentioned are currently implemented using reactive libraries). But upgrading to the latest version will fix this issue as such methods will be offloaded to worker thread, am I correct?
P.S: By reading Quarkus doc I understand that a minimal amount of I/O threads can handle many concurrent requests. I am curious by default how many I/O threads are there and is this configurable? Thanks!
You are correct in assuming that prior to Quarkus 2.2, the default for RESTEasy Reactive was to do handle the requests on the event-loop for all methods except when #Blocking was used.
It goes without saying that this means you need to not do any blocking IO (or have any long running operations for that matter) in these methods.
Quarkus uses 2*number_of_cpu_threads as the default number of event-loop threads it creates
I am very new to reactive programming, and currently working on microservice where in spring mvc is used and Spring Data MongoDb for database connectivity.
As I am going through spring data mongo db docs, there is support for reactive repositories, reative template api etc.
So Is there going to be any downside if I choose to use reactive templates and repository with blocking nature ?
Ex.
reactiveMongoTemplate.add(entity).block()
reactiveMongoTemplate.update(id, entity).block()
Also is there any significant difference with using calls like above than using blocking repository and template api itself ?
The answer depends on which stack you use: Spring WebFlux or Spring Web MVC.
In case of Spring WebFlux the choice is obvious: you have to use ReactiveMongoTemplate and never call block on it, instead return Mono/Flux as you get it from the template.
In case of Spring Web MVC you are free to use both the regular blocking MongoTemplate and ReactiveMongoTemplate with block. Although, in most cases you should go with the good old MongoTemplate for sake of simplicity and performance. ReactiveMongoTemplate has some overhead compared to the blocking MongoTemplate because the reactive types Mono/Flux put some additional pressure on memory.
I can imagine one use case where ReactiveMongoTemplate can provide some advantage even in Spring MVC: when during one HTTP request you have to execute multiple Mono operations concurrently. If you used blocking MongoTemplate then you would need to set up a thread pool and delegate the query execution there. However, with ReactiveMongoTemplate you could use the many operators of Mono and Flux to accomplish this task without worrying about threads, thread pools and scaling issues.
In the traditional programming you usually own the thread that you're running on, in the reactive programming its not the case. This "underlying unit of execution" (cpu resources consumer if you wish) is not yours, but rather a "global" thing that currently happens to execute your task, but can switch to do other things really soon.
So when you block, you say to this "global unit of execution" like "hey, stop doing anything else, wait for me". In the traditional approach, its kind of ok, because you have a thread associated with the current request, other requests (or flows if your system is not web based) are supposed to be executed with other threads taken from a fairly large thread pool. In the reactive system however, its not the case since you're trying to utilize a small amount of these "global units of execution".
Ok, so if you block, the events all over the place will stop emitting and will get start to buffer. And this may lead to the whole system becoming unusable.
Spring boot 2.1.5
Project Reactor 3.2.9
I am setting up a bunch of rest reactive APIs using the above-mentioned frameworks and I am running into an annoying problem with MDC (mapped diagnostic context). My applications are in JAVA.
MDC relies on thread locals to store the current query's mapped context to put in the logs. That system, obviously, is not perfect and contradicts the reactive pattern since the different steps of your execution will be executed through different threads.
I have run into the same problem with the Play Reactive framework but found a workaround there by copying the mapped context transparently from one actor to another.
For spring and reactor, I could not find a satisfying solution yet.
Some random examples found on the internet:
First - It works but forces you to use a bunch of utility methods
Same thing
Second - It tries to copy the context during the onNext publisher event but seems to lose some features on the way of doing that. The signal context, for example, is lost.
I am in need of a proper solution to deal with this:
A library which would make the link between MDC and reactor?
A way to tweak reactor/spring to achieve it transparently?
Any advice?
"I could not find a satisfying solution yet."
Working with contexts is the only solution for the moment. Since as you said threadlocals goes against everything that has to do with reactive programming. Using thread local as a storage point during a request is a resource heavy way of solving things and in my opinion poor design. Unless logging frameworks themselves come up with a better solution to the problem we developers must pass the data through the context to accommodate for the logging frameworks blocking nature.
Reactive programming is a paradigm shift in the programming world. Other things like database drivers, that use threadlocal to rollback transactions are also in big trouble. the JDBC database driver spec is defined as blocking in nature, and atm. there has been attempts by spring and the R2DBC project to define a new JDBC driver spec that is inherently non/blocking. This means that all vendors must rewrite ther database driver implementations from scratch.
Reactive program is so new that lots of libraries need to rewrite entire codebases. The logging frameworks as we know it needs to be rewritten from the ground up which is a huge task. And the context in reactive is actually something that should not even be in reactive programming, it was implemented just to accommodate for MDC problems.
It's actually a lot of overhead needing to pass data from thread to thread.
So what can we do?
push on logging frameworks, and/or help logging frameworks to rewrite their codebase
Accept that there is no "tweak" that will magically fix this
use the context and the way suggested in the blogposts
Project reactor context
Is it thread safe if i want to create an instance of some type via Prism container resolve method that was previously registered as singleton? Unfortunately i couldn't find any info on this.
It depends on what you mean by thread-safe, and depending on the answer to that, what implementation of ServiceLocator you are using.
Both MEF and Unity containers are thread-safe in the sense that Resolve can be called independently from multiple threads for the same type. Theoretically you could have some other kind of ServiceLocator which was not thread-safe in this respect, but I would be surprised to find one, because it would make thread synchronization across a Prism app a real chore.
What may not be thread-safe is the actual object that is returned from the container. For instance, if you registered a Dictionary object and asked for that back, there is nothing magical about ServiceLocator that would make the Dictionary's operations thread safe.
I'm working on a project where we use MULE and Spring. In the context we create beans that provide the services. All the beans are essentially thread safe singletons. Is this a popular/recommended way of writing services?
By default a bean in spring will be a singleton and it is a very common scenario you describe.
Might be problematic performance wise. If you have many threads competing for the same service. The bean is defined thread safe, so acess from different threads would be effectively serialized.
In our RESTFul service we set up our entry points on a
#com.sun.jersey.spi.resource.PerRequest
basis and
#org.springframework.context.annotation.Scope("request")
which keeps our throughput up but we monitor to ensure that GC is good enough not to bloat the app.
Spring singletons are inherently thread-safe plus this is the default scope -- which performs quite well as we use them in all our web apps.