Skip to content

Commit

Permalink
Merge pull request #327 from byroot/pooling-without-idle-timeout
Browse files Browse the repository at this point in the history
Allow to disable both connection pooling and pruning idependently
  • Loading branch information
mattbrictson committed Feb 3, 2016
2 parents 112d527 + 15716b7 commit 6de1e10
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 10 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ This file is written in reverse chronological order, newer releases will
appear at the top.

## `master` (Unreleased)

* `SSHKit::Backend::Netssh.pool.idle_timeout = 0` doesn't disable connection pooling anymore,
only connection expiration. To disable connection polling use `SSHKit::Backend::Netssh.pool.enabled = false`
* Add your entries below here, remember to credit yourself however you want
to be credited!
* make sure working directory for commands is properly cleared after `within` blocks
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -500,13 +500,18 @@ seconds. This timeout can be changed as follows:
SSHKit::Backend::Netssh.pool.idle_timeout = 60 # seconds
```

If you suspect the connection pooling is causing problems, you can disable the
pooling behaviour entirely by setting the idle_timeout to zero:
If you suspect the connection pruning is causing problems, you can disable the
expiration behaviour entirely by setting the idle_timeout to zero:

```ruby
SSHKit::Backend::Netssh.pool.idle_timeout = 0 # disabled
```

Or even disable the pooling entirely, but it will severely reduce performance:
```
SSHKit::Backend::Netssh.pool.enabled = false # disabled
```

## Tunneling and other related SSH themes

In order to do special gymnasitcs with SSH, tunneling, aliasing, complex options, etc with SSHKit it is possible to use [the underlying Net::SSH API](https://github.com/capistrano/sshkit/blob/master/EXAMPLES.md#setting-global-ssh-options) however in many cases it is preferred to use the system SSH configuration file at [`~/.ssh/config`](http://man.cx/ssh_config). This allows you to have personal configuration tied to your machine that does not have to be committed with the repository. If this is not suitable (everyone on the team needs a proxy command, or some special aliasing) a file in the same format can be placed in the project directory at `~/yourproject/.ssh/config`, this will be merged with the system settings in `~/.ssh/config`, and with any configuration specified in [`SSHKit::Backend::Netssh.config.ssh_options`](https://github.com/capistrano/sshkit/blob/master/lib/sshkit/backends/netssh.rb#L133).
Expand Down
19 changes: 13 additions & 6 deletions lib/sshkit/backends/connection_pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,35 @@ module Backend

class ConnectionPool

attr_accessor :idle_timeout
attr_accessor :idle_timeout, :enabled

def initialize
self.idle_timeout = 30
self.enabled = true
@mutex = Mutex.new
@pool = {}
end

def prune_expired?
idle_timeout && idle_timeout != 0
end

def checkout(*new_connection_args, &block)
entry = nil
key = new_connection_args.to_s
if idle_timeout
prune_expired
if enabled
prune_expired if prune_expired?
entry = find_live_entry(key)
end
entry || create_new_entry(new_connection_args, key, &block)
end

def checkin(entry)
if idle_timeout
prune_expired
entry.expires_at = Time.now + idle_timeout
if enabled
if prune_expired?
entry.expires_at = Time.now + idle_timeout
prune_expired
end
@mutex.synchronize do
@pool[entry.key] ||= []
@pool[entry.key] << entry
Expand Down
9 changes: 8 additions & 1 deletion test/unit/backends/test_connection_pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,16 @@ def test_connections_are_reused_across_threads_multiple_times
assert_equal t2[:conn], t3[:conn]
end

def test_zero_idle_timeout_disables_reuse
def test_zero_idle_timeout_disables_pruning
pool.idle_timeout = 0

conn1 = pool.checkout("conn", &connect)
assert_nil conn1.expires_at
end

def test_enabled_false_disables_pooling
pool.enabled = false

conn1 = pool.checkout("conn", &connect)
pool.checkin conn1

Expand Down

0 comments on commit 6de1e10

Please sign in to comment.