-
Notifications
You must be signed in to change notification settings - Fork 1.1k
GH-3980: Fix DefaultSftpSFactory for concurrency #3981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Fixes spring-projects#3980 When not `isSharedSession`, the `initClient()` is called for every session we request from the factory and in concurrent calls we end up with not initialized SSH client in some threads. * Add `synchronized` to the `initClient()` to block other threads while the first one initialize the client
|
I prepared slightly different approach with Double-checked locking: #3982 My approach might be slightly faster because:
|
| } | ||
|
|
||
| private void initClient() throws IOException { | ||
| private synchronized void initClient() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Synchronization has to be higher up - otherwise if isSharedSession is true, we could orphan a session; see code in getSession.
Lines 286 to 288 in f8fff81
| if (this.isSharedSession && freshSftpClient) { | |
| this.sharedSftpClient = sftpClient; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If isSharedSession we do this.sharedSessionLock.lock();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops - right; ignore.
|
|
||
| private void initClient() throws IOException { | ||
| private synchronized void initClient() throws IOException { | ||
| if (this.initialized.compareAndSet(false, true)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.initialized should not be set at the beginning of the method.
If initialisation fails, the variable will be set to true for uninitialized client.
Also, we can use volatile boolean instead of AtomicBoolean
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... Makes sense.
OK closing my PR.
Feel free to copy my unit test into your PR then we will review it and merge properly.
|
Closed in favor: #3982 |
Fixes #3980
When not
isSharedSession, theinitClient()is called for every session we request from the factory and in concurrent calls we end up with not initialized SSH client in some threads.synchronizedto theinitClient()to block other threads while the first one initialize the client