Skip to content

System.InvalidOperationException: The session is not open. #369

Closed
@kasharmaIVP

Description

@kasharmaIVP

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions