Cancelling Fetch results in client being Disconnected - mailkit

When cancelling IMailFolder.Fetch method with the cancellationToken, I get an exception that the client is disconnected.
I debugged MailKit and traced the issue to ImapEngine.Iterate() method where there is the following:
try {
while (current.Step ()) {
// more literal data to send...
}
if (current.Bye)
Disconnect ();
} catch {
Disconnect ();
throw;
} finally {
current = null;
}
Is it the right approach to disconnect the client on every exception type being caught?
Should this also apply to the case when we are cancelling the operation, so we can prioritize another operation, and we do not want to disconnect?

How else would you cancel a command that is in progress if not disconnecting the socket?

Related

How can you close a tokio-postgres connection?

In the tokio-postgres documentation in the first example, there is an example showing that you should run the database connection in a separate thread:
// The connection object performs the actual communication with the database,
// so spawn it off to run on its own.
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
});
If you do so, how can you kill that connection afterwards?
If you're on tokio 1, tokio::task::JoinHandle has an abort() function that cancels the task, thus dropping the connection.
let handle = task::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
}
handle.abort(); // this kills the task and drops the connection
Using my snippet as-is will immediately kill the task, thus this is probably not what you want in the end, but if you keep the handle around and use it e.g. in combination with some kind of shutdown listener you should be able to control the connection as wanted.

Jmeter - Force close a socket/wait until message recieved

I am opening a socket in jmeter (using groovy in JSR223 Sampler), and storing the message in a jmeter variable. This is the below code:
SocketAddress inetSocketAddress = new InetSocketAddress(InetAddress.getByName("localhost"),4801);
def server = new ServerSocket()
server.bind(inetSocketAddress)
while(!vars.get("caseId"))) {
server.accept { socket ->
log.info('Someone is connected')
socket.withStreams { input, output ->
InputStreamReader isReader = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isReader);
StringBuffer sb = new StringBuffer();
String str;
while((str = reader.readLine())!= null){
sb.append(str);
}
String finalStr = sb.toString()
String caseId = finalStr.split("<caseId>")[1].split("</caseId>")[0]
vars.put("caseId", caseId)
}
log.info("Connection processed")
}
}
if(vars.get("caseId"))
{
try
{
server.close();
vars.put("socketClose",true);
}
catch(Exception e)
{
log.info("Error in closing the socket: " + e.getMessage());
}
}
Now, there is some time delay between the first loop is executed and the message being recieved from the port. It doesnt receive the message immediately, and hence while loop is executed again. And then message is received and it sets caseId. It goes on to close the socket, because caseId is set. And that is throwing the error, because socket is still waiting for the message. So is there a way, to wait until socket has recieved all the messages, so i could properly close it?
Or just force close the socket, and Jmeter wont throw any exception?
Or when i execute next component, say IF controller in Jmeter, it waits until variable socketClose is set true? In that way, instead of while loops inside JSR223 sampler, i could use multiple If Controllers in Jmeter thread.
This is how ServerSocket.close() function works
public void close()
throws IOException
Closes this socket. Any thread currently blocked in accept() will throw a SocketException.
I don't think there is a way "to wait until socket has recieved all the messages" because Socket is dump as a rock and it can either listen for connections or shut down.
Maybe you might be interested in setSoTimeout() function?
Also this line:
vars.put("socketClose",true)
is very suspicious, I think you need to change it either to:
vars.put("socketClose", "true")
or to
vars.putObject("socketClose",true)
as JMeterVariables.put() function can accept only a String, see Top 8 JMeter Java Classes You Should Be Using with Groovy article for more details.

UWP streamsocket ping networktimer issues

I have a StreamSocket in UWP and I send my messages like this using a DataWriter object using the StoreAsync() method:
public static async Task<bool> SendNetworkMessage(NetworkMember member, NetworkMessage message)
{
DataWriter writer = member.DataWriter;
//Check that writer is not null
if (writer != null)
{
try
{
//Serialize Message
string stringToSend = SerializeObject<NetworkMessage>(message);
//Send Message Length
writer.WriteUInt32(writer.MeasureString(stringToSend));
//Send Message
writer.WriteString(stringToSend);
await writer.StoreAsync();
return true;
}
catch (Exception e)
{
Debug.WriteLine("DataWriter failed because of " + e.Message);
Debug.WriteLine("");
Disconnect(member);
OnMemberDisconnectedEvent(member);
return false;
}
}
else { return false; }
}
All is well, the only problem is that I don't know if a connection went down.
Now I want to check my connection using a DispatcherTimer like this:
private static async void NetworkTimer_Tick(object sender, object e)
{
foreach (NetworkMember member in networkMemberCollection)
{
if (member.Connected == true && member.Disconnecting == false)
{
await SendNetworkMessage(member, new PingMessage());
}
}}
However, this is causing timing issues which is causing ObjectDisposedExceptions on the DataWriter. It seems that the DispatcherTimer thread cannot use the StreamSocket when I send a message from a different thread. My question is: How can I make sure the Ping is sent each time but that SendNetworkMessage operations are done in order instead of overlapping?
Thanks
It seems that the DispatcherTimer thread cannot use the StreamSocket when I send a message from a different thread.
How can I make sure the Ping is sent each time but that SendNetworkMessage operations are done in order instead of overlapping?
It's possible, and I think your code using foreach and await operation can ensure the work of sending message in order.
the only problem is that I don't know if a connection went down.
If you want to know if the connection went down, you can refer to Handling WinRT StreamSocket disconnects (both server and client side).

Nodejs: How to catch exception in net.createServer.on("data",...)?

I've got a standard socket-server (NO HTTP) setup as follows (contrived):
var server = net.createServer(function(c) { //'connection' listener
c.on('data', function(data) {
//do stuff here
//some stuff can result in an exception that isn't caught anywhere downstream,
//so it bubbles up. I try to catch it here.
//this is the same problem as just trying to catch this:
throw new Error("catch me if you can");
});
}).listen(8124, function() { //'listening' listener
console.log('socket server started on port 8124,');
});
Now the thing is I've got some code throwing errors that aren't catched at all, crashing the server. As a last measure I'd like to catch them on this level, but anything I've tried fails.
server.on("error",....)
c.on("error",...)
Perhaps I need to get to the socket instead of c (the connection), although I'm not sure how.
I'm on Node 0.6.9
Thanks.
process.on('uncaughtException',function(err){
console.log('something terrible happened..')
})
You should catch the Exceptions yourself. There is no event on either connection or server objects which would allow you to handle exception the way you described. You should add exception handling logic into your event handlers to avoid server crash like this:
c.on('data', function(data) {
try {
// even handling code
}
catch(exception) {
// exception handling code
}

Design choice for automatically reconnecting socket client

I'm working with a windows form application in C#. I'm using a socket client which is connecting in an asynchronous way to a server. I would like the socket to try reconnecting immediately to the server if the connection is broken for any reason. Which is the best design to approach the problem? Should I build a thread which is continuously checking if the connection is lost and tries to reconnect to the server?
Here is the code of my XcomClient class which is handling the socket communication:
public void StartConnecting()
{
socketClient.BeginConnect(this.remoteEP, new AsyncCallback(ConnectCallback), this.socketClient);
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
// Signal that the connection has been made.
connectDone.Set();
StartReceiving();
NotifyClientStatusSubscribers(true);
}
catch(Exception e)
{
if (!this.socketClient.Connected)
StartConnecting();
else
{
}
}
}
public void StartReceiving()
{
StateObject state = new StateObject();
state.workSocket = this.socketClient;
socketClient.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnDataReceived), state);
}
private void OnDataReceived(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int iReadBytes = client.EndReceive(ar);
if (iReadBytes > 0)
{
byte[] bytesReceived = new byte[iReadBytes];
Buffer.BlockCopy(state.buffer, 0, bytesReceived, 0, iReadBytes);
this.responseList.Enqueue(bytesReceived);
StartReceiving();
receiveDone.Set();
}
else
{
NotifyClientStatusSubscribers(false);
}
}
catch (SocketException e)
{
NotifyClientStatusSubscribers(false);
}
}
Today I try to catch a disconnection by checking the number of bytes received or catching a socket exception.
If your application only receives data on a socket, then in most cases, you will never detect a broken connection. If you don't receive any data for a long time, you don't know if it's because the connection is broken or if the other end simply hasn't sent any data. You will, of course, detect (as EOF on the socket) connections closed by the other end in the normal fashion despite this.
In order to detect a broken connection, you need a keepalive. You need to either:
make the other end guarantee that it will send data on a set schedule, and you time out and close the connection if you don't get it, or,
send a probe to the other end once in a while. In this case the OS will take care of noticing a broken connection and you will get an error reading the socket if it's broken, either promptly (connection reset by peer) or eventually (connection timed out).
Either way, you need a timer. Whether you implement the timer as an event in an event loop or as a thread that sleeps is up to you and the best solution probably depends on how the rest of your application is structured. If you have a main thread that runs an event loop then it's probably best to hook in to that.
You can also enable the TCP keepalives option on the socket, but an application-layer keepalive is generally considered more robust.