I was reading through the .NET API Guide and it is pretty good information but I'm a bit confused on how RabbitMQ manages threads. Under the Concurrency Consideration section it states that every IConnection is backed up by a single background thread. Then it continues with:
The one place where the nature of the threading model is visible to the application is in any callback the application registers with the library. Such callbacks include:
any IBasicConsumer method
the BasicReturn event on IModel
any of the various shutdown events on IConnection, IModel etc.
I'm a bit confused by this. Do they mean that every time HandleBasicDeliver is called a new thread is created? In that case there will be as many threads as messages are received and the concurrency is controlled by the prefetch count along with the number of consumers?
So if we consider a case where I have one IConnection and two channels (IModel) with prefetch count of one and one EventingBasicConsumer per channel, how many threads would we have running in the application?
I have done considerable amount of research on this topic since I first asked the question so I thought I would post it here in case someone finds this information useful.
Take this with a grain of salt. These are my understandings of how rabbit (C#) works.
IConnection is an actual socket connection. It will have a single thread polling it. According to suggestions I have read, use one connection per application unless you have a reason to use more.
Using more than one connection does not necessarily mean that you have better fault tolerance since if a connection fails, there usually is a problem that will result in all the connections to fail. Also, in many cases using one connection is enough to handle the traffic coming from the network and it is simply unnecessary to have more.
http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-July/013771.html
http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2012-May/019873.html
In C# channels are not considered thread safe so it is not a bad idea to have a channel per thread, otherwise one should make sure to use locking mechanism.
https://www.rabbitmq.com/dotnet-api-guide.html
As per my understanding of reading the source code, handleBasicDeliver (and I think all IModel calls) is ran in a Task. With that in mind, having multiple consumers does increase the concurrency of your software since if one consumer receives a message and is busy processing it, another consumer is free to pick up a message and execute it in a different thread. Also, each consumer must be on its own channel to maximize concurrency otherwise message order is preserved. However, if that kind of concurrency is not welcome consider using a single channel to ensure the messages are processed in the order they arrived.
NOTE: Point 3 may have changed in that channel order is no longer preserved. I haven't had time to explore the new changes so read through this and draw your own conclusion:
https://github.com/rabbitmq/rabbitmq-dotnet-client/issues/251
I have revised my answer and research that you did looks good.
I have created an application using Rabbitmq and in that I had a situation where I have to share the same IConnection(Connection) for number of IModel(channel). And that is the way we should use one connection as one connection is enough for serving multiple channels.
The problem I faced once was if I am creating one connection per client then the number of connections for that queue goes on increasing which results in termination of the application after a while.
So we should avoid having multiple connections unless its needed. If possible only one connection should be used for multiple channels.
Various shut down events on IConnection, IModel:
The IModel even if goes down the IConnection is still there. But if the IConnection is down then all the IModel under that connection will be shut down.
Related
I'm trying to build this server that receives connections on a socket, authenticates the user and then "sends" the socket to the class of the user that matches it(with the info given in the authentication), to be added to a thread pool (of the multiple devices of that client) to be processed (exchanging information, updating things elsewhere, etc..).
I chose to do it this way because I don't want to be sending requests to the server 24/7, just keep a lightweight thread open for each device, communicating with it in real time.
Now, all I've seen so far that might do something like this is Socket.DuplicateAndClose, but that works for processes, not threads.
So is anyone aware of any way to do this, or should I take a different approach?
Thank you.
EDIT:
It seemed that there was some confusion, what I meant was, move it to another Socket inside another class, then the threads open on that class will process it. If I accept the connection to authenticate it, that socket then is having that connection, beforehand I couldn't have known to accept it with the specific socket in the specific class because I didn't know where it came from, and now, I have a thread I can't do anything with because I can't tell that class to use this thread, because if I do and use it in a thread of that class, the next socket I use to accept the connection will be the one that's occupied by that same class. I could use a huge array to store accepted sockets and tell classes that that socket number was theirs, but that would not only be limited but a bunch of loose sockets as well, which would work but would be neither optimized or organized.
There is no restriction on which threads access a given socket.
Any thread can perform operations on any socket (providing the thread's process has an open handle to that thread).
Performing multiple IO operations of the same type (eg. two reads) concurrently on one socket is likely to lead to confusion – you cannot control which will get the next data, and it could then complete second. But any form of explicit or implicit concurrence control can be used to avoid that.
(The same applies to other kernel objects like files, named pipes, shared memory sections, semaphores, …. The only thing that is restricted is only the thread holding a mutex or critical section can release it.)
I'm setting up a message queue where consumption of the message may occasionally fail for a while (due to, e.g., network downtime) and in this case I'd like to retry after some time has passed.
This is available in MSMQ's WCF binding under the name retry cycles and in NServiceBus under the name second-level retries. Is something similar available in MassTransit?
I haven't been able to find an answer to this in the MassTransit documentation. The closest thing to an answer I could find on the forum was in this thread which suggests the answer is no but offers some workarounds mostly involving blocking the consuming thread for some period of time. I'd rather have an implementation more like the two I referenced above that continues to process other messages until the retry delay has elapsed.
I don't believe there's a built-in way to handle this in MassTransit.
Let's consider your motivation for wanting to do a retry. You mention network downtime. This makes a lot of sense and is a good reason to inject some kind of delay before retrying a message again.
Given that case, however, wouldn't it stand to reason that if there is some kind of network downtime, that the same network downtime would affect the other messages in the queue? So, in fact, blocking the consumer thread isn't actually a problem. None of the messages are going to be successful, so let's just wait for a bit and try again later.
That's given the assumption that all the messages on your queue are pretty much doing the same thing (e.g. they're all generating some data that's being saved to a database server that's down).
If, however, there are many different message types in your queue, then I can definitely see why you wouldn't want to block processing of these other messages. Perhaps this would be a good time to take a look at the architecture of your consumers and see if splitting them up into multiple, purpose-built queues would make sense.
You can specify it at the bus level by UseRetry:
MassTransit.Bus.Factory.CreateUsingRabbitMq(cfg =>
{
// ...
cfg.UseRetry(retryConfig => retryConfig.Interval(2, TimeSpan.FromMinutes(1)));
// ...
}
I have a C# application which listens for incoming TCP connections and receive data from previously accepted connections. Please help me whether i use Threadpool or Async methods to write the program?? Note that, once a connection is accepted, it doesn't close it and continuously receive data from the connection, at the same time it accept more connections
A threadpool thread works best when the code takes less than half a second and does not a lot of I/O that will block the thread. Which is exactly the opposite scenario you describe.
Using Socket.BeginReceive() is strongly indicated here. Highly optimized at both the operating level and the framework, your program uses a single thread to wait for all pending reads to complete. Scaling to handle thousands of active connections is quite feasible.
Writing asynchronous code cleanly can be quite difficult, variables that you'd normally make local variables in a method that runs on the threadpool thread turn into fields of a class. You need a state machine to keep track of the connection state. You'll greatly benefit from the async/await support available in C# version 5 which allows you to turn those state variables back into local variables. The little wrappers you find in this answer or this blog post will help a great deal.
It mainly depends on what do you want to do with your connections. If you have unknown number of connections which you don't know how long they will be open, I think it's better to do it with async calls.
But if you at least know the avg. number of connection and the connections are short-term connections like a web server's connections, then it's better to do it with threadpool since you won't waste time creating threads for each socket.
First off, if you possibly can, don't use TCP/IP. I recommend you self-host WebAPI and/or SignalR instead. But if you do decide to use TCP/IP...
You should always use asynchronous APIs for sockets. Ideally, you want to be constantly reading from the socket and periodically writing (keepalive messages, if nothing else). What you don't want to do is to have time where you're only reading (e.g., waiting for the next message), or time where you're only writing (e.g., sending a message). When you're reading, you should be periodically writing; and when you're writing, you should be continuously reading.
This helps you detect half-open connections, and also avoids deadlocks.
You may find my TCP/IP .NET Sockets FAQ helpful.
Definately use asynchronous sockets... It's never a good idea to block a thread waiting for IO.
If you decide you have high performance needs, you should consider using the EAP design pattern for your sockets.
This will allow you to create an asynchronous solution with a lower memory profile. However, some find that using events with sockets is awkard and a bit clunky... if you fall into this category, you could take a look at this blog post to use .NET 4.5's async/await keywords with it: http://blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx#comments
I'm doing an application in C#, with a server and some clients (not more than 60), and I would like to be able to deal with each client independently. The communication between server and client is simple but I have to wait for some ack's and I don't want to block any query.
So far, I've done two versions of the server side, one it's based on this:
http://aviadezra.blogspot.com.es/2008/07/code-sample-net-sockets-multiple.html
and in the other one, I basically create a new thread for each client. Both versions work fine...but I would like to know pros and cons of the two methods.
Any programming pattern to follow in this sort of situation?
To answer your question it's both. You have threads and classes running in those threads. Whether you use WCF, async, sockets, or whatever, you will be running some object in a thread (or shuffled around a threadpool like with async). With WCF you can configure the concurrency model, and if you have to wait for ack's or other acknowledgement you'd be best to set it to multiple threads so you don't block other requests.
In the example you linked to the author is using AsyncCallback as the mechanism for telling you that a socket has data. But, from the MSDN you can see:
Use an AsyncCallback delegate to process the results of an asynchronous operation in a separate thread
So it's really no different for small scale apps. Using async like this can help you avoid allocating stack space for each thread, if you were to do a large application this would matter. But for a small app I think it just adds complexity. C# 4.5+ and F# do a cleaner job with async, so if you can use something like that then maybe go for it.
Doing it the way you have, you have a single thread that is responsible for socket management. It'll sit and accept new connections. When it gets a request it hands that socket to a new dedicated thread that will then sit on that socket and read from it. This thread is your client connection. I like to encapsulate the socket client reading into a base class that can do the low level io required and then act as a router for requests. I.e. when I get request XYZ I'll do request ABC. You can even have it dispatch events and subscribe to those events elsewhere (like in the async example). Now you've decoupled your client logic from your socket reading logic.
If you do things with WCF you don't need sockets and all that extra handling, but you should still be aware that calls are multi-threaded and properly synchronize your application when applicable.
For 60 clients I think you should choose whatever works best for you. WCF is easy to set up and easy to work with, I'd use that, but sockets are fine too. If you are concerned about the number of threads running, don't be. While it's bad to have too many threads running, most of your threads will actually be blocked while they are waiting on IO. Threads that are in a wait state aren't scheduled by the OS and don't really matter. Not to mention the waiting is most likely is using io completion ports under the hood so the wait overhead is pretty much negligible for a small application like yours.
In the end, I'd go with whatever is easiest to write, maintain, and extend.
I'm wondering if you have any recommendations to track down a tricky problem that involves UDP multicast packets being handled by multiple threads.
The problem always occurs when the program is started up, within 1 second of startup. So, I know the time window that the problem occurs in.
The problem occurs only once in about 20 runs of the program. The other 19 runs, it works flawlessly.
The program is reassembling the UDP multicast packets into data packets, if the problem occurs then the contents of the data packets are malformed (this can be checked with a CRC).
Are there any debugging techniques in .NET that you can use to track down bugs in multithreaded environments that involve network UDP packets?
How do I get visibility in such an environment?
Without more information, I can't give specific recommendations. I'd start with the following.
The first thing I'd do is check to see if there are possible race conditions in the code that aggregates and reassembles the packets. Somehow, you're taking packets from multiple threads and combining them. Typically this is done in one of two ways: either the individual threads queue packets for processing by a dedicated thread (a multiple producer, single consumer design), or you use some kind of synchronization that allows the threads to share a buffer. That is, each thread adds its incoming packet to the combined packet.
The former is easier to control. You can use a concurrent queue (such as the .NET BlockingCollection) and not worry about synchronization. If you're using a Queue<T> with a lock, or if your individual threads are cooperating to combine the packets, you have to make sure that there aren't any holes in your synchronization.
Another possibility is that one or more of the incoming packets is corrupt in some way, or the reader isn't reading it correctly. You should log every incoming packet along with the thread number and the time it came in. When the problem crops up, you can check the log to see if the packets are in good shape. If they are, then the problem is almost certainly with your synchronization.
Absent more information about your specific application, I don't have any other recommendations.