Say I have an #Async method call that hangs. Will it time out? What is best practise here to free you resources?
#Async method invocations are executed within a specified thread pool. If your method hangs, it will hold one thread from the pool infinitely. Spring can't do anything about it.
If your method is kind enough to accept InterruptedException, you can cancel it by calling Future.cancel() on a value returned from asynchronous method.
Related
The project I am working for is using Spring WebFlux. I came across a very odd issue.
The detail is that some of pieces of code are purely wrote in Reactor style (couples of Flux/Mono pipelines), however, in a inner publishers, I have to call a method where there is "Mono.block()" inside.
The weird thing I aware is that the whole service would become totally stuck, and when I captured a thread dump, I saw all those "nioEventLoopGroup-*" threads were hung.
A fun fact is that if I leverage a "simple" thread (new Thread(..)) to call the method (there is .block inside), everything works fine.
So my question is that, are those "nioEventLoopGroup-*" threads not allowed to call any blocking code.
Sorry for asking a dumb question, but it's blocking issue for now, so I am looking forward your insight.
Reactor, by default, uses a fixed size thread pool. When you use block(), the actual work needs to be done in some thread or another, which depends on the nature of the subscription and the Mono/Flux. Most likely a set of new tasks will be scheduled on the same scheduler, but block() will suspend its thread, waiting for those tasks to complete, so there is one fewer thread for those other tasks to be scheduled on. Evidently you have enough of these calls to exhauast the entire thread pool. All your block() calls are waiting for other tasks to complete, but there are no threads available for them to be run on.
There's no reason to call block() inside a mapping in a reactive stream. There are always other ways of achieving the same goal without blocking - flatMap(), zip() etc etc.
I have a asynchronous method enabled using #Async annotation. At times i am seeing SimpleAsyncTaskExecutor thread count increases exponentially. Any idea on this behavior?
If it increases literally exponentially it sounds like the async method is calling itself perhaps?
By default, Spring uses a SimpleAsyncTaskExecutor to run the methods asynchronously.
SimpleAsyncTaskExecutor spawns a new thread with each task and does not support thread pooling and queueing of tasks.
So, if the async method is called multiple times in a short span of time, multiple threads will be opened for each task
You should define your own executor. Refer the following link
http://www.baeldung.com/spring-async
When a TThread enters in Synchronized() method, it waits until EnterCriticalSection(ThreadLock) returns.
Now, which one will run the method if in the meantime, another Tthread, or even the main thread call some method of the waiting Tthread?
What could happen if in the meantime, another thread, or even the main thread call some method of the waiting thread?
Threads do not have methods, so this question is a non-sequitur.
It is not meaningful to ask what happens when you call a method of another thread. Because it is not possible to do so. When you call a method, that method executes on thread which called it.
A method like TThread.Synchronize schedules the execution of code onto a different thread. But, the body of TThread.Synchronize is executed by the thread of the caller.
A call to EnterCriticalSection cannot be interrupted by user mode code. So, suppose that thread A calls EnterCriticalSection at a point where thread B holds the lock. The call to EnterCriticalSection made on thread A will not return until thread B has released the lock. While thread A is blocked waiting to acquire the lock, no code will execute on thread A.
It seems, from clarifications in the comments, that your question is in fact:
When a method of TThread is called, on which thread does that method execute?
The answer is that the method is executed on the calling thread. There's nothing special about the TThread class and so the normal rules apply.
I'm trying to use boost::asio for the first time to write a process that connects to N servers reads data from them.
My question regards the way in which asynchronicity works. My design goal is to connect to all servers in parallel, and also read data from every server in parallel. This should be done with async_connect and async_read, and calling io_service::run() N times, then reading the results. And the question is: is it enough to call io_service::run() from a single thread, sequentially, N times, in order to achieve parallelism?
Note that this is a matter of the implementation of asio: specifically, when calling connect_async and write_async, does the call signal the OS to begin connecting/reading before returning, or does it simply delegate a synchronous connect/read task to the worker thread and returns immediately? - case in which calling io_service::run() from a single thread means serial execution of tasks.
My guess is the former, of course, but I need someone to please confirm. I find it off that the documentation for async stuff (http://think-async.com/Asio/boost_asio_1_3_1/doc/html/boost_asio/overview/core/basics.html) doesn't mention when the async_xxx calls return, which would clarify my question.
The heart of asio is an event loop, which begins with the call to io_service::run(), which is a blocking call. When you call async_connect, you queue up the connect operation in the io_services event queue. To achieve parallelism, you must create a thread pool and have each thread call run() on the same io_service instance.
I've noticed that if I create an NSURLConnection and fire the request, all is well. My delegate methods get called and the last delegate method get's called well after the code block invoking the connection completes. Great.
That leads me to believe the connections are asynchronous which implies that they're multi-threaded. Is that correct? Could they be asynchronous but in the same thread? No, that's crazy - right?
But, in every example I've seen using an NSOperation, NSURLConnections are always scheduledInRunLoop after which [runLoop runMode ...] is invoked in a while loop.
Can someone explain exactly what is happening here? It seems to me that the first case requires spawning secondary threads but no manual invocation of the run loop (on those threads) while NSOperation (in a new thread) does require manual invocation of the run loop.
Why is no manual invocation required for the first case?
NSURLConnection does spawn a single background thread to manage all instances of itself, but this is generally irrelevant to the caller, since the delegate calls are made on whatever thread owns the runloop the connection was scheduled in. (This fact turned out to be very relevant to me recently, but these things really only come up when dealing with insane crashers in multi-threaded apps.)
For more caller-relevant details, you should look at the docs for -[NSURLConnection scheduleInRunLoop:forMode:]. It explains how to manually handle scheduling and unscheduling, and how NSURLConnections behave in a multi-threaded environment.
If you are unclear on how run loops work and how they perform asynchronous actions without requiring additional threads, you should read Run Loops in the Threading Programming Guide. This is a very important topic for moving to more advanced Cocoa development.
Because the main thread already has a run loop, I'd imagine.
If you want to run NSURLConnection in another thread, you should create a run loop like this in your thread's main method:
while (!finished)
{
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}