I am using Ktor 2.1.1 webserver in my Java/Kotlin application. Now I have the problem, that 2 different routes are processed within the same thread. But in the first route I have to block before returning the response until another route is called from a sub-process on my system. So with random assignment sometimes these two route-calls are ending up in the same thread which is blocked then.
Is there any possible chance that a call for a route can be assigned to a thread or excluded from each other to be executed on the same thread?
Thank you very much,
Thomas
Related
I suppose, there is a thread pool which the web server are using to serve requests. So the controllers are running within one of the thread of this thread pool. Say it is the 'serving' pool.
In one of my async action method I use an async method,
var myResult = await myObject.MyMethodAsync();
// my completion logic here
As explained many places, we are doing this, to not block the valuable serving pool thread, instead execute MyMethodAsync in an other background thread... then continue the completion logic in again a serving pool thread, probably in other one, but having the http context, and some othe minor things marshaled there correctly.
So the background thread in which MyMethodAsync runs must be from an other thread pool, unless the whole thing makes no sense.
Question
Please confirm or correct my understanding and in case if it is correct, I still miss why would one thread in one pool more valuable resource than other thread in another pool? In the end of the day the whole thing runs on a same particular hardware with given number of cores and CPU performance...
There is only one thread pool in a .NET application. It has both worker threads and I/O threads, which are treated differently, but there is only one pool.
I suppose, there is a thread pool which the web server are using to serve requests. So the controllers are running within one of the thread of this thread pool. Say it is the 'serving' pool.
ASP.NET uses the .NET thread pool to serve requests, yes.
As explained many places, we are doing this, to not block the valuable serving pool thread, instead execute MyMethodAsync in an other background thread... then continue the completion logic in again a serving pool thread, probably in other one, but having the http context, and some othe minor things marshaled there correctly.
So the background thread in which MyMethodAsync runs must be from an other thread pool, unless the whole thing makes no sense.
This is the wrong part.
With truly asynchronous methods, there is no thread (as described on my blog). While the code within MyMethodAsync will run on some thread, there is no thread dedicated to running MyMethodAsync until it completes.
You can think about it this way: asynchronous code usually deals with I/O, so lets say for example that MyMethodAsync is posting something to an API. Once the post is sent, there's no point in having a thread just block waiting for a response. Instead, MyMethodAsync just wires up a continuation and returns. As a result, most asynchronous controller methods use zero threads while waiting for external systems to respond. There's no "other thread pool" because there's no "other thread" at all.
Which is kind of the point of asynchronous code on ASP.NET: to use fewer threads to serve more requests. Also see this article.
My application queries 7 marketplaces in a row using Indy HTTP client. All marketplaces provide a unified interface to request/response. That said, the structure of request/response is the same for all 7 marketplaces.
I submit GTIN to a MainForm's TEdit box and the app posts 7 RESTful requests to the marketplaces and returns XML responses for all of them.
My idea is to wrap each request in a separate thread, but I am really concerned by the performance issues. Normaly I perform 1 request in 3-5 seconds.
Each thread is created in a for statement and initalizes TIdHTTP object, makes a request, gets an XML-response, parses it and ships it back to the MainForm.
When the job is done each thread needs to be terminated (or paused?)
If the thread completely terminates, then it must perform the same initialization routine on a next request. I find it relatively slow, assuming 7 thread initializations at a time.
However, if the thread is paused it merely resides in memory, has all its factories initialized and is ready to accept next requests.
How do I leave the thread operationally terminated, but still completely initialized? I assume, if TIdHTTP and XML-parsing objects stay alive in a paused thead, they will act much faster on the next request. Does it have any sense?
I can't imagine how can node.js in one single thread execute two scripts with different code simultaneously. For example I have two different scripts A and B. What will happen if almost simultaneously several clients request A and B. For PHP it is understandable, for example, will be created five threads to handle A and five threads to handle B, and for each request script executes again. But what happens in Node.js? Thank you!
It uses the so called event loop, implemented by libuv
A very simple explanation would be: when a new event occurs, it will be put into a queue. Every now and then, the node process will interupt execution to process these events.
The main difference between PHP and node is that a node.js process is essentially a stand-alone web server (single threaded), while PHP is an interpreter that runs within a web server (i.e. Apache), which is responsible for creating new threads for each request.
Node.js is very good for network applications (like web sites) because in these applications most of the work is I/O which node.js handles asynchronously.
Even if two requests arrive at the same time and Node.js only has one single thread of execution, each one of the requests (in sequence) will be handed off to the operating system for I/O (via libuv as mihai pointed out) and the fact that there is only one JavaScript thread of execution becomes irrelevant. As the I/O completes, the JavaScript thread picks up the result and returns a response.
I'm code reviewing a WCF service.
In the header of each message we inject data that the service is going to use later to build a connection string to a DB.
That's because the service is going to be used by a number of different sites, each with its own DB that the service has to query.
We use wcf extensibility. We have a custom MessageInspector that, after receiving the request, extracts the data from the message header, creates a context (that implements IExtension) and adds it to OperationContext.Current.Extensions.
Before sending the reply the custom context is removed from the Extencions collection.
This is a fairly common pattern, as discussed here:
Where to store data for current WCF call? Is ThreadStatic safe?
and here:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/319cac66-66e8-4dfe-9a82-dfd289c9df1f/wcf-doesnt-have-session-storage-so-where-should-one-store-call-specific-data?forum=wcf
This all works fine as long as the service receives a request, processes it, sends the reply and receives the next request.
But what if the service receives a request and before being able to reply it gets a second request? I built a small console application to test it. I send 2 messages from 2 different threads, I made the wcf service wait for 2 seconds, to ensure the second request comes in before the first one is completed and this is what I get:
Site Id : test1450 ; Session: uuid:2caf47cf-7d46-4d72-9275-d9c037fa0e70;id=2 : Thread Id: 6
Site Id : test1450 ; Session: uuid:2caf47cf-7d46-4d72-9275-d9c037fa0e70;id=3 : Thread Id: 22
It looks like wcf creates 2 sessions executing on 2 different threads, but Site Id is the same. It shouldn't. Judging from this it looks like OperationContext.Current.Extensions is a collection shared between threads.
Right now I'm inclined to think my test is wrong and I missed something.
Has anyone tried something similar and found out that OperationContext.Current is not thread safe?
OperationContext.Current like other similar properties such as HttpContext.Current have thread affine (or thread static) values. So they are thread safe in the sense that multiple threads can read them, but different threads will get different instances. They can be thought of as dictionaries between specific threads and instances.
So in this context they are not thread safe.
Requests are served by a thread pool so concurrent requests will have different thread ids. (up to a point where the thread pool is full, then requests will be put on hold)
In my BlackBerry app, the Locator.geocode(...) request is inside a Thread but it still blocks the UI in OS 5 devices. In OS 6 and 7 devices it works fine. The UI is not blocked.
From the moment Locator.geocode(...) is called till it finishes the UI is blocked and user can't interact with the application.
I guess this is a OS 5 issue. Is there a solution for this?
Update: First of all, thanks for quick replies.
I replaced Locator.geocode(...) call for Thread.sleep(...). The UI gets slowed down but not blocked. The simulator I'm using is 9300.
The Locator.geocode(...) request is inside a try..catch() block and it throws no Exceptions. After the call finishes it returns null (I'm using simulator) but no exception are being thrown.
For your information, this is what the console prints: (Using 9300 simulator)
**** Number of threads before creating Geocode class: 4
**** Number of threads inside Geocode class just before calling Locator.geocode: 5
**** Running on event thread: false
Locator.geocode(...) // UI blocks at this point(OS 5) till this
request finishes
Are you sure you have it running on a thread properly? It may be that OS 6+ is just responding faster, so you only notice the problem on OS 5. Try replacing the call to Locator.geocode() with a call to Thread.sleep(60000) to make sure the background thread is working properly.
From the Locator documentation:
*Requests for geocode information are synchronous, but can be interrupted by invoking cancel(). An application can use the Locator class to make only one request at a time. Making more than one request results in a MapServiceException. *
So thats one thing to check in your code. Make sure you don't make multiple request. Another possible problem:
If the LBS Map API is not installed on a BlackBerry device, requests for geocode information will throw a MapServiceException.
In both cases, an exception being thrown in a thread will terminate that thread, but this wont affect other threads like the event thread. So, without reading the code, I'd say your problem is not related to locator. It will be really helpful if you pasted some code or an exception trace.