Replies: 5 comments
-
Are you looking for "idle" connections which are still perfectly healthy but just haven't been used in a while, or "stale" connections, where the connection has broken at something like the TCP level but something in the network failed to notify you about that break (like NAT state timing out)? The existing keep alive mechanism should be enough to detect the latter, and make sure that connections get cleaned up when this happens. Also, you can potentially catch errors when trying to open a new session on a connection and retry with a new connection (or a different connection in the pool) when a failure occurs. If you're truly looking to close connections which haven't been used in a while, why not do that at the application level? Whenever you send a new request on a connection in the pool you could cancel and restart an idle timer. If that timer goes off at any point, you could remove the idle connection from the pool and close it. I'm assuming here that requests are processed quickly enough that you wouldn't have to worry about the idle timer going off while some existing request is still being processed, but you could guard against that by checking if there are active sessions on a connection before trying to close it, and instead reset the idle timeout if it goes off with a request still in progress. |
Beta Was this translation helpful? Give feedback.
-
I am considering the first scenario, a healthy connection that has not been used for a while and is considered "idle". Keeping track if a connection is idle on the application side would be possible indeed. But is it the best design? Having this logic wrapped around SSHClientConnection might be more error prone and overall a less elegant solution. |
Beta Was this translation helpful? Give feedback.
-
I'm not against adding some kind of idle timeout -- there are already other timeouts such as As for reducing code duplication - I'm not sure that's the case. To support both this timeout and the existing keep-alive, two different timers would need to be scheduled (independent of one another), since each is reset under different conditions. So, different member variables would be needed to keep track of the new timeout, and new functions would be needed to set/clear it, called from the appropriate places. Also, note that reads and writes of data happen at the session level, not at the connection level. If there was an idle timeout implemented, I would expect it to be at the session level, so you could have an open SSH connection with multiple sessions open in parallel and it should be possible for one of those sessions to time out without affecting others. If I understand your use case, you're really looking for a way to clean up your connection pool, which is implemented at the application level. So, having the timeout implemented at the application level seems like the best option, especially if the conditions which reset the timeout are tied to adding and removing connections from the connection pool. |
Beta Was this translation helpful? Give feedback.
-
Yes your analysis is mostly correct. Having such information provided by the connection would make for a much more robust design. Regardless of the use-case and the connection pool design I believe that knowing if a connection is idle should be a responsibility of the connection object itself not an external entity. For additional context here is the code that "borrows" the connection and the one that prunes the connection pool:
|
Beta Was this translation helpful? Give feedback.
-
Does each use of a connection involve creating a new SSH session on the connection pulled from the pool? I'm guessing it does, to allow multiple requests to be simultaneously using a connection without stepping on one another. If that's the case, is this session closed when the request is complete, even though the connection remains open (and usable for additional requests)? If sessions are closed when a request is done with them, you should be able to track how many open sessions there are on each connection. When doing your prune check, you could skip any connections which have a non-zero session count, avoiding the risk of pruning a connection which is in use. You'd just need to add something that increments the session count when a new session is opened and decrements it when the session is closed. You could still keep an idle timeout before you pruned connections, but it would only prune those with a session count of 0. This might allow your timeout to be lower, since there'd be no risk of pruning a connection with sessions still active. This seems like a pretty clean solution to me, with nearly all of the logic all in your connection pool class. |
Beta Was this translation helpful? Give feedback.
-
Hi there,
I would love to discuss the following idea or alternative solutions.
Idea
add an Idle property to the SSHClientConnection to indicate when a connection has gone idle
Motivation
We are using asyncssh to power a REST API for HPC resource access. To cope with high throughput regimes (> 250 requests/s) we are implementing a SSH connection pool to leverage existing connections for subsequent commands execution.
In order to maintain and mange the connections within the pool we have the necessity to evict stale connections. As of today there is no method to tell if a SSHClientConnection has gone idle.
Implementation Design
Leveraging the existing keep_alive method to set the idle flag as soon as the first keep_alive timer triggers. Receiving or sending data would reset the idle flag.
Beta Was this translation helpful? Give feedback.
All reactions