I know that actors inside Service Fabric are single-threaded. But suppose I start a new thread inside an actor method, what will happen then? Will an actor be deactivated even though the spawned thread is still executing?
According to the documentation, an actor is deactivated when it has not been 'used' for some time. 'Used' in this context means either:
receiving a call
IRemindable.ReceiveReminderAsync being invoked
So it seems that the new thread I started is not taken into account. But maybe someone can confirm this?
Actors are just object.
The Actor will be deactivated and it becomes available for garbage collection.
Actual threads in the OS (when running) keep running until they complete or terminate. Their managed representation can be collected, but this doesn't affect the actual thread.
Also, threads spawned inside an Actor are not tracked in any way, so you're responsible to manage their life cycle yourself.
Exactly.
When you start a new thread, the original thread(The actor) will continue running and go out of scope, and the spanned thread continue running. look what happens then:
When an actor receive a call, the thread handling this call will acquire a lock using a SemaphoreSlim to handle the actor object, if another thread has already acquired the lock, the current thread will wait for its release, so that it can continue once free.
Once the lock is acquired, the thread will execute and return from the method called, and them release the lock for the following thread to continue.
When you span a new thread as part of the actor logic, it will just run as part of the service process, but the problem here is that once you leave the method scope, you won't have control of this thread anymore, but it will keep running, and for the actor runtime the task has finished, the next actor call will create another thread, and the things will keep going.
The problem will start when:
You don't have control how many threads are running, your services will start consuming too much memory and SF might try to balance the actors\services across instances, because it does not know about these threads, if it move the actor service, all you threads will be aborted and you loose these operations.
The spanned thread from previous call will compete with the new thread for the next actor call.
If the new thread uses the actor data to continue other operation both, the spanned thread and the actor thread will face concurrency issues, in cases where no exception happens you will have strange behaviors where you can't investigate easily. For example, one thread changing a value being used by the other.
And many other concurrency issues you might face
In scenarios where you might(think) need another thread you could:
Create another actor to handle the task
Create a message in a queue to be processed by another service
Do the task as part of the actor call.
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.
A COM application based on the 'free' threading model subscribes to events published from another COM application that runs out of process.
The application works normally. But in some cases (or configurations?) it burns through a lot of so called Tpp worker threads.
These threads apparently belong to a thread pool managed by Windows/COM. And they are at least used by COM to deliver incoming events to the application.
When the application receives events, that always happens in the context of one of these worker threads.
In the normal situation, updates are coming in from at most 2 or 3 unique worker threads.
But in the abnormal situation the application sees new & unique worker thread IDs appear every 3-8 minutes. Over the course of a week the application has seen about 1000 unique threads (!).
I highly suspect there is something wrong here. Because surely the thread pool doesn't need so many different threads, right?
What could be a reason for the thread pool behavior I'm seeing. Is it just normal that it creates different threads from time to time? Are the old threads still sticking around doing nothing? What action could trigger this while the application is running in the context of the worker thread?
Notes:
Our application is an OPC DA client (and the other application is the Siemens OPC-DA server)
The OS is Windows 10
I do not yet know if the worker threads have exited or that they stick around doing nothing
By way of an experiment I have tried several bad/illegal things to see if it is possible for our application to somehow break a worker thread
- which would then explain why the thread pool would have to create a new one - we might have destroyed the old one. But that seems more difficult than I had expected:
When running in the context of the worker thread, I have tried...
deliberately hanging with while (true) {}, result: event delivery process just stalls, no new worker thread is being created for us though
the deliberate uncaught c++ exception, no new worker thread is created
triggering a deliberate (read) access violation, no new thread either...
And that got me thinking, if our application can't kill that worker thread in an obvious way, what else could or why would the thread pool behave like this?
I want to implement something akin to work stealing or task migration in multiprocessor systems. Details below.
I am simulating a scheduling system with multiple worker nodes (resources, each with multiple capacity), and tasks (process) that arrive randomly and are queued by the scheduler at a specific worker node. This is working fine.
However, I want to trigger an event when a worker node has spare capacity, so that it steals the front task from the worker with the longest wait queue.
I can implement the functionality described above. The problem is that all the tasks waiting on the worker queue from which we are stealing work receive the event notification. I want to notify ONLY the task at the front of the queue (or only N tasks at the front of the queue).
The Bank reneging example is the closest example to what I want to implement. However, it (1) ALL the customers leave the queue when they are notified that the event was triggered, and (2) when event is triggered, the customers leave the system; in my example, I want to make the task wait at another worker (though it wouldn't wait, since the queue of that worker is empty).
Old question: Can this be done in SimPy?
New questions: How can I do this in SimPy?
1) How can I have many processes, waiting for a resource, listen for an event, but notify only the first one?
2) How can I make a process migrate to another resource?
I'm building a multi-threaded service application in Delphi XE2. Each thread serves its own purpose apart from the other ones. The main service thread is only responsible for keeping the other threads going and saving a log file, etc. Each of these threads reports back to the main service thread through synchronized event triggers. These threads are created when the service starts and destroyed when the service ends.
I'd like to introduce a separate thread as a centralized database connection to avoid having to create many instances of TADOConnection. My service code can call standard functions such as UserListDataSet := DBThread.GetUserList(SomeUserListDataSet); or it would also be nice if I could send direct SQL statements like SomeDataSet := DBThread.Get(MySqlText);. I'd also like to avoid too many occasions of CoInitialize() etc.
The job threads will need to use this db thread. I need to figure out how to "ask" it for certain data, "wait" for a response, and "acquire" that response back in the thread which requested it. I'm sure there are many approaches to this, but I need to know which one is best suited for my scenario. Windows messages? Events? Should I have some sort of queue? Should it send data sets or something else? Is there already something that can do this? I need to figure out how to structure this DB thread in a way that it can be re-used from other threads.
The structure looks like this:
+ SvcThread
+ DBThread
+ TADOConnection
+ Thread1
+ Thread2
+ Thread3
I need threads 1 2 and 3 to send requests to the DBThread. When a thread sends any request to it, it needs to wait until it gets a response. Once there's a response, the DB Thread needs to notify the asking thread. Each of the threads might send a request to this DB Thread at the same time too.
A good tutorial on how to accomplish this would be perfect - it just needs to be a suitable fit for my scenario. I don't need to know just "how to make two threads talk together" but rather "how to make many threads talk to a centralized database thread". These job threads are created as children of the main service thread, and are not owned by the db thread. The db thread has no knowledge of the job threads.
Normally, you'd have a request queue where all the requests are stored. Your database thread reads a request from the queue, handles it, then invokes a callback routine specified by the requester to handle the result. Not sure how this maps to Delphi paradigms, but the basics should be the same.
Do any of the "requesting" threads have anything profitable that they could be doing while they are waiting for a response to be obtained from the database? If the answer is "no," as I suspect that it is quite likely to be, then perhaps you can simplify your situation quite a bit by eliminating the need for "a DB thread" completely. Perhaps all of the threads can simply share a single database-connection in turn, employing a mutual-exclusion object to cause them to "wait their turn."
Under this scenario, there would be one database-connection, and any thread which needed to use it would do so. But they would be obliged to obtain a mutex object first, hold on to the mutex during the time they were doing database queries, and then release the mutex so that the next thread could have its turn.
If you decide that it is somehow advantageous (or a necessity...) to dedicate a thread to managing the connection, then perhaps you could achieve the result using (a) a mutex to serialize the requests, as before; and (b) one event-object to signal the DB-thread that a new request has been posted, and (c) another event-object to signal the requester that the request has been completed.
In either case, if you have indeed determined that the requester threads have nothing useful that they could be doing in the meantime, you have the threads "simply sleeping" until their turn comes up. Then, they do their business, either directly or indirectly. There are no "queues," no complicated shared data-structures, simply because you have (say...) determined that there is no need for them.
I think using a DB connection pool would be a better fit for your problem. This would also allow you to scale your application later on without having to then create additional DB thread and then having to manage "load balancing" for those DB threads.
Since you are mentioning using TADOConnection please have a look at this implementation made by Cary Jensen http://cc.embarcadero.com/item/19975.
I am successfully using this DB connection pool in several applications. I have modified it in several ways, including using an ini file to control: maximum number of connections, cleanup time, timeout times etc.
Cary has written several articles that serves as documentation for it. One is here http://edn.embarcadero.com/article/30027.
I'm writing the application, which connects to the DB and repetitively (1 minute interval) reads the data from a database. It's something like RSS feed reader, but with local DB. If the data reading fails, I try to reestablish the connection. I've designed it with TADOConnection and TADOQuery placed on the form (so with no dynamic creation). My aim is to keep the application "alive" from the user's point of view, so I placed the connection and the reading part into a single thread. The question is, how to do it best way ?
My design looks like this:
application start, the TADOConnection and TADOQuery are created along with the form
open connection in a separate thread (TADOConnection)
if the connection is established, suspend the connection thread, start the timer on the form, which periodically resumes another thread for data reading
if the reading thread succeeds, nothing happens and form timer keeps going, if it fails, the thread stops the timer and resume connection thread
Is it better to create TADOConnection or TADOQuery dynamically or it doesn't matter ? Is it better to use e.g. critical section in the threads or something (I have only one access to the component at the same time and only one thread) ?
Thanks for your suggestions
This question is fairly subjective, probably not subjective enough to get closed but subjective any way. Here's why I'd go for dynamically created ADO objects:
Keeps everything together: the code and the objects used to access the code. Using data access objects created on the form requires the Thread to have intimate knowledge of the Form's inner workings, that's never a good idea.
It's safer because you can't access those objects from other threads (including the main VCL thread). Sure, you're not planing on using those connections for anything else, you're not planning on using multiple threads etc, but maybe you'll some day forget about those restrictions.
It's future-proof. You might want to use that same thread from an other project. You might want to add an second thread accesing some other data to the same app.
I have a personal preference for creating data access objects dynamically from code. Yes, an subjective answer to a subjective question.
Run everything in the thread. Have a periodic timer in the thread that opens the DB connection, reads the data, "posts" it back to the main thread, and then disconnects. The thread needs to "sleep" while waiting for the time, e.g. on a Windows even that is signalled by the timer. The DB components, which are local and private to the thread, can be created inside the thread when thread executions starts (on application startup), and freed when thread execution finishes (on application shutdown). This will always work, regardless of whether the DB conncetion is temporarily available or not, and the main thread does not even have to communicate with the "DB thread". It is an architcture that I use all the time and is absolulutely bullet-proof.