Description
Hi
I am running on renci latest version 2016.1.0.0
Trying to upload/poll/download and delete in sequence using 4 different static SFTP connections for these individual operations. This all happens in multi-threaded environment with a throttle of 100 parallel threads.
The dispose happens at once, only when all the threads are finished.
Problem : After a few files I start getting the following error in either of these operations (upload/poll/download/delete).
_SFTP - Error in SFTP Upload. Retry attempt number : 9. Exception : System.InvalidOperationException: The session is not open.
at Renci.SshNet.SubsystemSession.EnsureSessionIsOpen()
at Renci.SshNet.SubsystemSession.SendData(Byte[] data)
at Renci.SshNet.Sftp.SftpSession.SendRequest(SftpRequest request)
at Renci.SshNet.Sftp.SftpSession.RequestRealPath(String path, Boolean nullOnError)
at Renci.SshNet.Sftp.SftpSession.GetCanonicalPath(String path)
at Renci.SshNet.SftpClient.InternalUploadFile(Stream input, String path, Flags flags, SftpUploadAsyncResult asyncResult, Action`1 uploadCallback)
at Renci.SshNet.SftpClient.UploadFile(Stream input, String path, Action`1 uploadCallback)_
Following is the GetInstance method to create the 4 static connection on first request:
public SftpClient GetInstance(string instanceID)
{
if (_edmSftpClient == null || _edmSftpClient.ContainsKey(instanceID) == false)
{
lock (((ICollection)_edmSftpClient).SyncRoot)
{
if (_edmSftpClient == null || _edmSftpClient.ContainsKey(instanceID) == false)
{
string _domain = _credential.Domain.Replace("sftp://", "").Replace("ftp://", "");
ConnectionInfo ConnNfo = new ConnectionInfo(_domain, 22, _credential.UserName, new AuthenticationMethod[]
{
new PasswordAuthenticationMethod(_credential.UserName, _credential.Password),
new PrivateKeyAuthenticationMethod(_credential.UserName,_pkFileClient.ToArray()),
}
);
logger.Info(string.Format("Creating SFTP for blockInstance: {0}", instanceID));
if (_credential.Domain != null)
_edmSftpClient.Add(instanceID, new SftpClient(ConnNfo) { OperationTimeout = TimeSpan.FromDays(1), KeepAliveInterval = TimeSpan.FromDays(1) });
else
throw new Exception("SFTP Domain not set.");
}
}
}
if (_edmSftpClient[instanceID].IsConnected == false)
{
lock (((ICollection)_edmSftpClient).SyncRoot)
{
if (_edmSftpClient[instanceID].IsConnected == false)
{
_edmSftpClient[instanceID].ConnectionInfo.MaxSessions = 99999999;
_edmSftpClient[instanceID].ConnectionInfo.Timeout = TimeSpan.FromDays(1);
_edmSftpClient[instanceID].Connect();
}
}
}
_edmSftpClient[instanceID].ErrorOccurred += (object sender, ExceptionEventArgs e) =>
{
logger.Error(string.Format("_edmSftpClient.ErrorOccurred event captured with exception {0}", e != null && e.Exception != null ? e.Exception.ToString() : "no error message recorded"));
};
return _edmSftpClient[instanceID];
}
And here is the sample Upload method that I have written. Trying for 10 retries:
public void Upload(string remotePath, string remoteFileName, byte[] stream)
{
EDMSftpClient _sftpClient = null;
int _retryCount = 10;
while (true)
{
try
{
logger.Info(string.Format("Uploading File : {0}. RemotePath : {1}", remoteFileName, remotePath));
_sftpClient = new EDMSftpClient(Credential);
_sftpClient._pkFileClient = pkFile;
string r = GetRemotePathNoServer(remotePath, remoteFileName);
var _uInstance = _sftpClient.GetInstance("U" + _blockInstanceID);
_uInstance.UploadFile(new MemoryStream(stream), r, (x) =>
{
logger.Info(string.Format("Uploaded File : {0}. RemotePath : {1}", remoteFileName, remotePath));
});
break;
}
catch (Exception ex)
{
_retryCount--;
logger.Error(string.Format("Error in SFTP Upload. Retry attempt number : {0}. Exception : {1}", _retryCount, ex));
if (_retryCount == 0)
throw;
Thread.Sleep(1000 * _retryCount);
}
}
}
This happens intermittently after some time. Have tried playing around with properties like ConnectionInfo.MaxSessions, KeepAliveInterval, ConnectionInfo.Timeout. But no luck.
And the confusion is the the _edmSftpClient[instanceID].IsConnected property evaluates to true while I get this error.
Can you please suggest where am I going wrong. Could it be SFTP server setting issue or a code bug.