-
Notifications
You must be signed in to change notification settings - Fork 255
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
Fix open two connections with changed cache key #392
Conversation
Hi @shirosaki thanks for the patch! I'm really glad to see tests, and that you solved a bug. I'm not a 100% happy with the implementation copying changes into the cache keys.. maybe we could find another way to derive cache keys. I'd be happy to merge this as-is (it has a test for correct behaviour) and eventually one-day re-evaluate (maybe) how we derive cache keys. In short LGTM, I'm happy to merge if one of the other maintainers is! |
Thanks for the PR! I definitely think you are onto something here: the idea of re-computing the key after opening the connection sounds like a workaround I would be happy with. However I have some concerns with the current implementation:
Is there a way you could rework this PR to address these points? Also, some nitpicks:
|
da5ff1f
to
41f9811
Compare
Thanks for feedback. The bug is due to option values changing and the cache key of I updated the patch for the following points.
|
Thanks for the changes. I need some more time to review and think this over. It looks to me like this could be simplified even further, but I haven't figured it out yet. |
I think there are a couple things I would change about this PR. First, the test is not really an accurate reproduction of the original bug (#369). In the bug, the same SSH options hash is passed both times, and the hash contains the same keys both times. It is only the value of one the keys ( If we change the test to specifically cover only this scenario, then the code changes needed to make that test pass become a bit more simple: all we need to do is compare the key (i.e. Since this re-keying only needs to happen for the Anyway, I have pushed a commit to your branch with these proposed changes. Let me know what you think! |
Thanks for the commit. Indeed simplified. I did some fixes to avoid password twice.
:password_prompt and :logger options are added in net-ssh |
Yes, you are right. This bug goes much deeper than I originally realized. Thanks for pointing out that Maybe it is just me, it is difficult to follow what exactly is happening in the code, and as I've discovered it takes a lot of digging to understand why the workaround is written the way it is. I would therefore like to hold off on merging this PR. Perhaps there is a better way to solve this? What if we opened a PR at net-ssh to change how they handle default options such that they make a copy of the options hash instead of modifying it in place? Would that make our workaround easier? |
43d6aa2
to
5a80b0d
Compare
I found another fix. |
Very promising! This looks great. I'll review in more detail tomorrow. Thanks |
return if cache.same_key?(new_key) | ||
|
||
caches.synchronize do | ||
cache = caches[new_key] = caches.delete(cache.key) |
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.
Is the chained assignment really needed here? I find it a bit hard to read.
If I remove the extra assignment and just write:
caches[new_key] = caches.delete(cache.key)
cache.key = new_key
… then the tests still pass.
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.
You are right. I'll fix it.
Awesome! ✨ I think this is good to merge, provided you can:
Thanks for all your hard work on fixing this bug! |
`args.to_s` is used for cache key of connection pooling. `ssh_options` in `args` is changed while creating connections in `connection_factory.call(*args)`. Updating cache key with changed `args` prevents cache miss.
5a80b0d
to
4edb96f
Compare
Thanks for review.
|
There is one functional test that is failing:
If you are unable to run the functional tests locally, I can take care of it. Let me know! |
:password_prompt and :logger options are added in net-ssh `Net::SSH.assign_defaults`. Set default options early for ConnectionPool cache key. The key in Cache object should be updated for comparing next time.
4edb96f
to
3e748a1
Compare
Fixed functional test. BTW functional test causes many errors on Windows. |
Thanks for pointing that out. The functional tests don't work on Travis either, so there is definitely a lot of room for improvement! |
Tests all pass. Thank you so much for this PR and all your research! 🙇 |
## [1.13.1][] (2017-03-31) ### Breaking changes * None ### Bug fixes * [#397](https://github.com/capistrano/sshkt/pull/397): Fix NoMethodError assign_defaults with net-ssh older than 4.0.0 - [@shirosaki](https://github.com/shirosaki) ## [1.13.0][] (2017-03-24) ### Breaking changes * None ### New features * [#372](capistrano/sshkit#372): Use cp_r in local backend with recursive option - [@okuramasafumi](https://github.com/okuramasafumi) ### Bug fixes * [#390](capistrano/sshkit#390): Properly wrap Ruby StandardError w/ add'l context - [@mattbrictson](https://github.com/mattbrictson) * [#392](capistrano/sshkit#392): Fix open two connections with changed cache key - [@shirosaki](https://github.com/shirosaki)
args.to_s
is used for cache key of connection pooling.ssh_options
inargs
is changed while creating connections inconnection_factory.call(*args)
.Resetting cache key using changed
args
prevents cache miss.This is a workaround for #369.