I use RabbitMQ.Client (runtime version v2.0.50727, version 2.8.1.0) with C# .NET application.
I create connection like this:
using (IConnection connection = _factory.CreateConnection())
{
using (IModel channel = connection.CreateModel())
{
// code...
}
}
If I close the application properly, it simply closes the channel and connection. But if application is closed incorrectly (e.g. pressing restart button on PC), it is not. I would like to ensure that all unnecessary connections (from previous sessions or even other applications, if by mistake other instance of the application is running somewhere else) are closed before I start my application.
I know I may use heart beats but it is possible that my application requires really much time to start doing anything (many hours of opened connection and not being used). So I think heartbeat is not the best thing.
How can I close all opened connections for RMQ? (Or, even better, all opened connections, with the exception for one given IP)?
Regards!
I encountered the same problem as you. I tried a lot of methods to close those connections.
Those methods, some are works some are only part works. Maybe you can have a try.
Use rabbitmqctl command to delete the queues then use RMQ's management website close the connections. It means current opened queues will expire after 1 second(1000 miliseconds). This way all queues are deleted. Then you can close connections.
Command:
rabbitmqctl set_policy expiry ".*" '{"expires":1000}' --apply-to queues
Queue Time-To-Live policy--> https://www.rabbitmq.com/ttl.html
This method works partly.
After searching, got the idea that reason might be:
Your producer waiting the return ACK back, it won't be destroyed untill you send ACK to acknowledge the job has finished.
Abrupt way. Works. RMQ save connections information in its DB menisa.
Step1: Stop rabbitmq-server first, and kill rabbitmq thread by 'ps aux | grep rabbitmq' to find its pid then kill all rabbitmq thread.
Find RMQ DB mensia location
(1). $> cd /var/lib/rabbitmq/
Step2: rename mensia file to another name to "delete"
(2). $> mv mensia mensia-bak
Step3: restart rabbitmq-server
The third methods works for me now. It can close all open connections.
Sounds like Heartbeats is your best solution. I added heartbeats to my RabbitMQ apps for the same reason (ungraceful shutdowns). It shouldn't matter that there is a long gap of time between messages, heartbeat will just verify that the connection is still open on both sides.
I had the same problem when I open worker in console and than stop it with ctrl+c. After than process is closed but connection is still there and it's visible in admin panel.
One solution is to close connection in RabbitMQ Admin panel
or you can found the process and kill it manual sudo kill -9 pid
or when you open an connection set HEARTBEAT. Read [Dead TCP Connections]
Related
Is there a way to stop a remote connection?
In more detail if a WCF connection is created using the ChannelFactory
var aChannelFactory = new ChannelFactory<ISomeService>(aBinding, aEndpoint);
and the connection is used via GSM, it makes sense to enlarge timeouts so that
aChannelFactory.CreateChannel();
has the possibility to connect to the remote site.
Now the problem is that a user may have the wish to stop the creation of a connection (Abort a getting connencted window, only use offline part of a programm).
But how is this possible?
The CreateChannel-call is synchronous.
Even if it is wrapped in a thread, nowadays Thread.Abort should not be used.
Is there any way to stop the creation of a channel automatically?
Or must it be "faked" to a user, so that the connection still is running until its timeout (or success) even is user decided to work temporarely offline?
As Grant Thomas stated it is not necessary to abort the connection.
I would like to check my internet connection while using WebClient in order to download a file. (WebClient.DownloadFile()).
I want to check if the connection still available in the middle of the downloading process.
How do I do that ? (in C#)
Thanks a lot.
You cannot generally detect that the internet is available or not. But heuristically, you can start a second thread which tries to GET google.com with a read timeout of 5s every 15s or so. That way your connection check can have different, harder timeouts than your main download.
You can't. There is no way in TCP to check the status of a connection other than by trying to use it. Set a read timeout, and respond accordingly to the resulting SocketTimeoutException; and respond to any other IOException by closing the connection and maybe retrying, depending on your specific requirements.
I have a problem in the code that I have written using .NET.
The problem is that somewhere I have some dodgy database code that means that after some time I get the following error:
Timeout expired. The timeout period
elapsed prior to obtaining a
connection from the pool. This may
have occurred because all pooled
connections were in use and max pool
size was reached.
I know that it is because somewhere I haven't disposed of one of my datareaders or something similar which means it still has the connection open so its not being returned to the pool. I'm having a bit of problem finding where this is happening in my code though.
So my question:
Is there any way to query the connection pool to find out what its in use connections are doing. I'm just looking for a way to find what query is being run to allow me to find the offending piece of code.
For what its worth I don't have permissions to run an activity monitor on the database in question to find out that way.
Is there any way to query the
connection pool to find out what its
in use connections are doing.
No. Not really. The connection pool is something that your application maintains (actually a List<DbConnectionInternal> ) If you really wanted to you could get to the connections in the pool via reflection or if you are debugging, via a local or watch window (see below), but you can't get to what's happening on that connection from there or which object should have called Connection.Close (or Dispose). So that doesn't help
If you're lucky you can execute sp_who or sp_who2 at the moment you get the timeout when you've run out of pooled connections when but its highly likely that most of the results are going to look like this .
SPID Staus Login Hostname Blkby DBname Command ....
---- ------- ----- --------- ----- ------ ----------------
79 sleeping uName WebServer . YourDb AWAITING COMMAND .....
80 sleeping uName WebServer . YourDb AWAITING COMMAND .....
81 sleeping uName WebServer . YourDb AWAITING COMMAND .....
82 sleeping uName WebServer . YourDb AWAITING COMMAND .....
Which means that yes indeed your application has opened a lot of connection and didn't close them and isn't even doing anything with them.
The best way to combat this is to profile your application use the ADO.NET Performance Counters and keep a close eye on NumberOfReclaimedConnections and also do a thorough code review.
If you're really desperate you can Clear the pool when you encounter this problem.
using (SqlConnection cnn = new SqlConnection("YourCnnString"))
{
try
{
cnn.Open();
}
catch (InvalidOperationException)
{
SqlConnection.ClearPool(cnn);
}
cnn.Open();
}
I do however caution you against this because it has the potential of choking your DB server because it allows your application to open as many connections as the server will allow before it just runs out of resources.
Have you tried loading up SSMS and running sp_who2 on the database in question?
USE [SomeDatabase]
EXEC sp_who2
That should show you what's happening at a moment in time.
I have implemented a wcf P2P setup in a simple application.
My question is the result of testing this with multiple clients. Nine times out of ten, all the clients will synch up in the mesh and connect without issue.
However, depending on which client I close and then re-open, it will not reconnect to the mesh. The other clients do not see it.
My question is how can I perhaps close and re-open the p2p on this client so it can attempt to connect again? I'd set a timer perhaps that every minute or so if it isn't connected, it might assume there is an issue so it would close it's p2p endpoint or whatever and then re-open it to refresh the whole thing.
I ask this since if I close this client, then re-open it, it will reconnect to the mesh.
I want fool-proof connections. Such as, you open a client and the client will figure out if it has to restart or it isn't getting connection after a certain amount of time so it attempts to "flush" the connection and rebuild it.
Does this make sense?
It's going to be difficult to determine that you're not connected to the mesh because of some unknown fault condition rather than simply being alone.
The IOnlineStatus property on the peer channel can tell you if you're alone in the mesh (false), or if you have connected peers (true). You can get this property by registering for the status change event like so:
IOnlineStatus status = myPeerChannel.GetProperty<IOnlineStatus>();
status.Online += new EventHandler(MyOnlineEventHandler);
status.Offline += new EventHandler(MyOfflineEventHandler);
So I suppose one way to do this would be to have a timer that checks your online status and if you go more than X amount of time being offline, dispose of your channel and create a new one.
If i have a client that is connected to a server and if the server crashes, how can i determine, form my client, if the connection is off ? the idea is that if in my client's while i await to read a line from my server ( String a = sr.ReadLine(); ) and while the client is waiting to recieve that line , the server crashes , how do i close that thread that contains my while ?
Many have told me that in that while(alive) { .. } I should just change the alive value to true , but if my program is currently awaiting for a line to read, it won't get to exit the while because it will be trapped at sr.ReadLine() .
I was thinking that if i can't send a line to the server i should just close the client thread with .abort() . Any Ideas ?
Have a TimeOut parameter in ReadLine method which takes a TimeSpan value and times out after that interval if the response is not received..
public string ReadLine(TimeSpan timeout)
{
// ..your logic.
)
For an example check these SO posts -
Implementing a timeout on a function returning a value
Implement C# Generic Timeout
Is the server app your own, or something off the shelf?
If it's yours, send a "heart beat" every couple of seconds to let the clients know that the connection and service are still alive. (This is a bit more reliable than just seeing if the connection is closed since it may be possible for the connection to remain open while the server app is locked.)
That the server crashes has nothing to do with your clients. There are several external factors that can make the connection go down: The client is one of them, internet/lan problems is another one.
It doesn't matter why something fails, the server should handle it anyway. Servers going down will make your users scream ;)
Regarding multi threading, I suggest that you look at the BeginXXX/EndXXX asynchronous methods. They give you much more power and a more robust solution.
Try to avoid any strategy that relies on thread abort(). If you cannot avoid it, make sure you understand the idiom for that mechanism, which involves having a separate appdomain and catching ThreadAbortException
If the server crashes I imagine you will have more problems than just fixing a while loop. Your program may enter an unstable state for other reasons. State should not be overlooked. That being said, a nice "server timed out" message may suffice. You could take it a step further and ping, then give a slightly more advanced message "server appears to be down".