-
Notifications
You must be signed in to change notification settings - Fork 90
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
Enable caching on connections #214
Conversation
9fa599f
to
b4a4785
Compare
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.
@jquick I really like the shape of this. I know this isn't exactly what @chris-rock was pitching initially, but after you and I talked about it, I think this is a better approach. It ensures that we don't have to do any Ruby magic to make the "Cache" connection have all the instance messages for the connection it represents, and it cleanly extends caching to ANY connection that subclasses BaseConnection
. I think this is a more Rubyish way to accomplish this. Nice work.
I have some cleanup items and suggestions for you to review, and we can talk to @chris-rock more about this next week.
lib/train/plugins/base_connection.rb
Outdated
# @param command [String] command string to execute | ||
# @return [CommandResult] contains the result of running the command | ||
def run_command_via_connection(_command) | ||
fail Train::ClientError, "#{self.class} does not implement #run_command_via_connection()" |
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.
I think we should raise a NotImplementedError
instead as that's the standard exception class for this type of issue. Is there a reason we shouldn't?
lib/train/plugins/base_connection.rb
Outdated
def file(_path, *_args) | ||
fail Train::ClientError, "#{self.class} does not implement #file(...)" | ||
def file_via_connection(_path, *_args) | ||
fail Train::ClientError, "#{self.class} does not implement #file_via_connection(...)" |
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.
I think we should raise a NotImplementedError
instead as that's the standard exception class for this type of issue. Is there a reason we shouldn't?
} | ||
|
||
@cache_enabled.each_key do |type| | ||
@cache[type] = {} |
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.
Maybe call clear_cache
here instead?
|
||
class Train::Plugins::Transport | ||
class CacheConnection | ||
attr_accessor :cache_enabled |
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.
Ruby nitpick, I'd rather see a cache_enabled?
method that looks at this hash and returns true/false... just to keep consistency with ?
methods returning booleans. If you choose to take this advice, this will obviously require some changes in BaseConnection, but not too many.
end | ||
|
||
def file(path) | ||
if @cache[:file].key?(path) |
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.
Could this be simplified to?:
@cache[:file][path] ||= @connection.file_via_connection(path)
That should return the value if it's there, otherwise, assign the new value and then return it.
end | ||
|
||
def run_command(cmd) | ||
if @cache[:command].key?(cmd) |
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.
Same as above - I think we can do ||=
and simplify a bit.
test/unit/plugins/connection_test.rb
Outdated
@@ -14,6 +14,10 @@ | |||
proc { connection.run_command('') }.must_raise Train::ClientError | |||
end | |||
|
|||
it 'provides a run_command_via_connection method' do |
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.
I wonder if this should be it 'raises an exception for run_command_via_connection'
, and then we add a it 'provides a run_command_via_connection method'
check for each of our connection classes. Thoughts?
test/unit/plugins/connection_test.rb
Outdated
@@ -22,6 +26,10 @@ | |||
proc { connection.file('') }.must_raise Train::ClientError | |||
end | |||
|
|||
it 'provides a file_via_connection method' do | |||
proc { connection.file_via_connection('') }.must_raise Train::ClientError |
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.
Same as above...
53b774c
to
e853f12
Compare
This should be updated with all changes to date. |
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.
I think we are very close @jquick
# | ||
# @param command [String] command string to execute | ||
# @return [CommandResult] contains the result of running the command | ||
def run_command_via_connection(_command) |
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.
Those two methods need to be private
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.
Yes, moved.
else | ||
Train::File::Remote::Linux.new(self, path) | ||
end | ||
def uri |
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 there a reason to make this public?
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.
I think we need it for now as inspec calls it here: https://github.com/chef/inspec/blob/master/lib/inspec/rspec_json_formatter.rb#L561
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.
Missed it, thank you.
nil # none, open your shell | ||
end | ||
|
||
def uri |
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.
Why are we exposing this one?
lib/train/transports/mock.rb
Outdated
end | ||
|
||
def file_via_connection(path) | ||
@files[path] ||= file_not_found(path) |
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.
Should we use the file cache and just fill the cache? So this will become a noop then
Signed-off-by: Jared Quick <jquick@chef.io>
Signed-off-by: Jared Quick <jquick@chef.io>
Signed-off-by: Jared Quick <jquick@chef.io>
Signed-off-by: Jared Quick <jquick@chef.io>
Signed-off-by: Jared Quick <jquick@chef.io>
e853f12
to
231bae3
Compare
This is updated with all changes. |
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 looks great, I added some further comments. Would love to see this in action with https://github.com/chef/inspec/pull/2309/files before we merge. @jquick are you updating inspec/inspec#2309
lib/train/plugins/base_connection.rb
Outdated
@cache_enabled[type.to_sym] | ||
end | ||
|
||
def enable_cache(type) |
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.
I think we need a comment to document which types are available.
lib/train/plugins/transport.rb
Outdated
@@ -1,7 +1,4 @@ | |||
# encoding: utf-8 | |||
# | |||
# Author:: Dominik Richter (<dominik.richter@gmail.com>) |
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.
I am not sure why this is removed?
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.
It was a directive via Adam to remove any author tags on files we touch. I can add it back for now.
Signed-off-by: Jared Quick <jquick@chef.io>
This has been updated with changes. inspec/inspec#2309 was also updated to use this new functionality. |
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.
Great work @jquick
else | ||
Train::File::Remote::Linux.new(self, path) | ||
end | ||
def uri |
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.
Missed it, thank you.
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 is so freakin' close. I have a suggestion on making the run_command
and file
method just read a bit cleaner and remove some logic when returning.
lib/train/plugins/base_connection.rb
Outdated
# Enable caching types for Train. Currently we support | ||
# :file and :command types | ||
def enable_cache(type) | ||
@cache_enabled[type.to_sym] = 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.
Future enhancement: raise an exception if the user tries to enable/disable a cache that we don't support.
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.
+1 great catch!
lib/train/plugins/base_connection.rb
Outdated
# This is the main command call for all connections. This will call the private | ||
# run_command_via_connection on the connection with optional caching | ||
def run_command(cmd) | ||
return @cache[:command][cmd] ||= run_command_via_connection(cmd) if cache_enabled?(:command) |
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.
I think it might be a bit cleaner to read if it was structured to do the non-cache enabled stuff first:
return run_command_via_connection(cmd) unless cache_enabled?(:command)
@cache[:command][cmd] ||= run_command_via_connection(cmd)
The return
combined with the ||=
is hanging me up a bit. Feels like too much happening in one conditional statement.
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.
Uh, I like that one. Thank you @adamleff
lib/train/plugins/base_connection.rb
Outdated
# This is the main file call for all connections. This will call the private | ||
# file_via_connection on the connection with optional caching | ||
def file(path, *args) | ||
return @cache[:file][path] ||= file_via_connection(path) if cache_enabled?(:file) |
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.
Same feedback as the run_command
structure feedback.
Signed-off-by: Jared Quick <jquick@chef.io>
lib/train/plugins/base_connection.rb
Outdated
@@ -43,10 +43,12 @@ def cache_enabled?(type) | |||
# Enable caching types for Train. Currently we support | |||
# :file and :command types | |||
def enable_cache(type) | |||
fail Train::UnknownCacheType, "#{type} is not a valid cache type" unless @cache_enabled.keys.include?(type.to_sym) |
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.
Rather than getting a list of the keys, you can ask the Hash if it has the key:
... unless @cache_enabled.key?(type.to_sym)
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.
Nice work, @jquick :)
This changes adds a new connection called "CacheConnection". When passed a connection it will cache file and command calls. All connection methods will be accessible on the cached version.
Signed-off-by: Jared Quick jquick@chef.io