rutty 2.3.2 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/rutty/helpers.rb CHANGED
@@ -2,7 +2,7 @@ require 'rutty/errors'
2
2
  require 'rutty/version'
3
3
 
4
4
  module Rutty
5
-
5
+
6
6
  ##
7
7
  # Simple mixin module for miscellaneous methods that don't fit in elsewhere.
8
8
  #
@@ -17,10 +17,10 @@ module Rutty
17
17
  def check_installed!
18
18
  unless File.exists? self.config_dir
19
19
  raise Rutty::NotInstalledError.new %Q(Can't find conf directory at #{self.config_dir}.
20
- Run `rutty init' first. (Or rutty --help for usage))
20
+ Run `rutty init' first. (Or rutty --help for usage))
21
21
  end
22
22
  end
23
-
23
+
24
24
  ##
25
25
  # Returns the version string contained in {Rutty::Version::STRING}. Used by the rutty bin.
26
26
  #
@@ -29,5 +29,35 @@ module Rutty
29
29
  def self.get_version
30
30
  Rutty::Version::STRING
31
31
  end
32
+
33
+ ##
34
+ # Returns a string formatted to a more human-readable representation of a time difference in seconds.
35
+ #
36
+ # @since 2.4.0
37
+ #
38
+ # @param [Float] seconds_total The number of seconds to convert
39
+ # @return [String] The formatted string
40
+ def seconds_in_words seconds_total
41
+ hours = seconds_total / 3600
42
+ minutes = (seconds_total - (3600 * hours)) / 60
43
+ seconds = (seconds_total % (hours >= 1 ? (3600 * hours) : 60)) % 60
44
+
45
+ out = ''
46
+
47
+ unless hours < 1
48
+ out << hours.to_s
49
+ out << ((hours > 1) ? " hours " : " hour ")
50
+ end
51
+
52
+ unless minutes < 1
53
+ out << minutes.to_s
54
+ out << ((minutes > 1) ? " minutes " : " minute ")
55
+ end
56
+
57
+ out << seconds.to_s
58
+ out << ((seconds > 1) ? " seconds" : " second")
59
+
60
+ out.strip
61
+ end
32
62
  end
33
63
  end
data/lib/rutty/node.rb CHANGED
@@ -9,6 +9,18 @@ module Rutty
9
9
  # @author Josh Lindsey
10
10
  # @since 2.0.0
11
11
  class Node < Config
12
+ class << self
13
+ ##
14
+ # Override the inherited {Rutty::Config.load_config} method, raising an exception
15
+ # to indicate improper usage.
16
+ #
17
+ # @since 2.3.3
18
+ # @raise [RuntimeError] On call, as this class has no use for this method
19
+ def load_config dir
20
+ raise "Unable to call load_config on Node objects."
21
+ end
22
+ end
23
+
12
24
  ##
13
25
  # Initialize a new {Rutty::Node} instance by merging the user-provided data with
14
26
  # the configured defaults.
@@ -54,4 +66,4 @@ module Rutty
54
66
  self.tags == other.tags
55
67
  end
56
68
  end
57
- end
69
+ end
@@ -0,0 +1,80 @@
1
+ require 'thread'
2
+ require 'fastthread'
3
+ require 'rutty/thread_pool/worker'
4
+
5
+ module Rutty
6
+
7
+ ##
8
+ # A thread pool implementation using the work queue pattern. Shamelessly stolen from a StackOverflow question.
9
+ #
10
+ # @see http://stackoverflow.com/questions/81788/deadlock-in-threadpool/82777#82777
11
+ # @since 2.4.0
12
+ class ThreadPool
13
+ ## @return [Integer] The maximum number of concurrent {Worker} threads
14
+ attr_accessor :max_size
15
+
16
+ ##
17
+ # Creates a new {ThreadPool} instance with a maximum number of {Worker} threads.
18
+ def initialize max_size = 10
19
+ Thread.abort_on_exception = true
20
+
21
+ @max_size = max_size
22
+ @queue = Queue.new
23
+ @workers = []
24
+ end
25
+
26
+ ##
27
+ # The current size of the <tt>@workers</tt> array.
28
+ #
29
+ # @return [Integer] The current number of {Worker} threads
30
+ def current_size
31
+ @workers.size
32
+ end
33
+
34
+ ##
35
+ # Whether any {Worker} threads are currently executing, determined by
36
+ # comparing the sizes of the <tt>@workers</tt> array and the <tt>@queue</tt>.
37
+ #
38
+ # @return [Boolean] Any currently executing workers?
39
+ def busy?
40
+ @queue.size < current_size
41
+ end
42
+
43
+ ##
44
+ # Loops over every {Worker} and calls {Worker#stop}, then clears the <tt>@workers</tt> array.
45
+ def shutdown
46
+ @workers.each { |w| w.stop }
47
+ @workers = []
48
+ end
49
+
50
+ alias :join :shutdown
51
+
52
+ ##
53
+ # Gets a free worker and passes it the specified closure.
54
+ #
55
+ # @see #get_worker
56
+ # @param [Proc, Lambda, #call] block An instance of any class that responds to <tt>#call</tt>
57
+ def process block = nil, &blk
58
+ block = blk if block_given?
59
+ get_worker.set_block block
60
+ end
61
+
62
+ private
63
+
64
+ ##
65
+ # Gets a free {Worker}. If the {#max_size} has been reached and the <tt>@queue</tt> isn't empty,
66
+ # pops an existing {Worker} from there. Otherwise spins up a new {Worker} and adds it to the <tt>@workers</tt>
67
+ # array.
68
+ #
69
+ # @return [Rutty::Worker] A {Worker} ready for a new job
70
+ def get_worker
71
+ if !@queue.empty? or current_size == @max_size
72
+ return @queue.pop
73
+ else
74
+ worker = Rutty::Worker.new @queue
75
+ @workers << worker
76
+ worker
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,103 @@
1
+ require 'thread'
2
+ require 'fastthread'
3
+
4
+ module Rutty
5
+
6
+ ##
7
+ # The {ThreadPool} Thread wrapper, representing a single thread of execution in the pool.
8
+ #
9
+ # @since 2.4.0
10
+ class Worker
11
+
12
+ ##
13
+ # Initialize a new {Worker}. Sets up the initial state of this instance, then spins out its thread. The thread will
14
+ # wait until it's signaled (by being passed a new closure to execute, or being told to die, etc.), then resume execution
15
+ # of its task. The Thread is wrapped in a <tt>while @running</tt> loop, allowing for easy termination from {#shutdown}.
16
+ #
17
+ # @param [Queue] thread_queue The thread queue from the {ThreadPool} instance to add this worker to
18
+ # @return [Worker] The new, available Worker object.
19
+ def initialize thread_queue
20
+ @mutex = Mutex.new
21
+ @cv = ConditionVariable.new
22
+ @queue = thread_queue
23
+ @running = true
24
+
25
+ @thread = Thread.new do
26
+ @mutex.synchronize do
27
+ while @running
28
+ @cv.wait @mutex
29
+ block = get_block
30
+
31
+ if block
32
+ @mutex.unlock
33
+ block.call
34
+ @mutex.lock
35
+ reset_block
36
+ end
37
+
38
+ @queue << self
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ ##
45
+ # Returns the evaluation of <tt>@thread.inspect</tt>.
46
+ #
47
+ # @return [String] This thread's name
48
+ def name
49
+ @thread.inspect
50
+ end
51
+
52
+ ##
53
+ # Returns the value of <tt>@block</tt>.
54
+ #
55
+ # @return [Proc, Lambda, #call] The <tt>@block</tt> object previously passed.
56
+ def get_block
57
+ @block
58
+ end
59
+
60
+ ##
61
+ # Sets a new closure as the task for this worker. Signals the Thread to wakeup after assignment.
62
+ #
63
+ # @param (see Rutty::ThreadPool#process)
64
+ # @raise [RuntimeError] If the thread is currently busy when called.
65
+ def set_block block
66
+ @mutex.synchronize do
67
+ raise RuntimeError, "Thread already busy." if @block
68
+ @block = block
69
+ # Signal the thread in this class, that there's a job to be done
70
+ @cv.signal
71
+ end
72
+ end
73
+
74
+ ##
75
+ # Sets the <tt>@block</tt> to <tt>nil</tt>. Called after the Thread has finished execution of a task to
76
+ # ready itself for the next one.
77
+ def reset_block
78
+ @block = nil
79
+ end
80
+
81
+ ##
82
+ # Whether or not this Thread is currently executing. Determined by whether <tt>@block</tt> is <tt>nil</tt>.
83
+ #
84
+ # @return [Boolean] Is this Thread executing?
85
+ def busy?
86
+ @mutex.synchronize { !@block.nil? }
87
+ end
88
+
89
+ ##
90
+ # Sets <tt>@running</tt> to <tt>false</tt>, causing the Thread to finish after the current loop. Signals
91
+ # the Thread to wake and resume, then calls <tt>#join</tt>.
92
+ #
93
+ # @see #initialize
94
+ def stop
95
+ @mutex.synchronize do
96
+ @running = false
97
+ @cv.signal
98
+ end
99
+
100
+ @thread.join
101
+ end
102
+ end
103
+ end
data/lib/rutty/version.rb CHANGED
@@ -8,8 +8,8 @@ module Rutty
8
8
  # @see http://semver.org
9
9
  module Version
10
10
  MAJOR = 2
11
- MINOR = 3
12
- PATCH = 2
11
+ MINOR = 4
12
+ PATCH = 0
13
13
  BUILD = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
data/rutty.gemspec CHANGED
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rutty}
8
- s.version = "2.3.2"
8
+ s.version = "2.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Josh Lindsey"]
12
- s.date = %q{2010-11-15}
12
+ s.date = %q{2010-11-24}
13
13
  s.default_executable = %q{rutty}
14
14
  s.description = %q{
15
15
  RuTTY is a DSH (distributed / dancer's shell) written in Ruby. It's used to run commands
@@ -20,63 +20,66 @@ Gem::Specification.new do |s|
20
20
  s.executables = ["rutty"]
21
21
  s.extra_rdoc_files = [
22
22
  "LICENSE",
23
- "README.md"
23
+ "README.md"
24
24
  ]
25
25
  s.files = [
26
- ".gitignore",
27
- ".yardopts",
28
- "Gemfile",
29
- "Gemfile.lock",
30
- "LICENSE",
31
- "README.md",
32
- "Rakefile",
33
- "VERSION",
34
- "bin/rutty",
35
- "lib/rutty.rb",
36
- "lib/rutty/actions.rb",
37
- "lib/rutty/config.rb",
38
- "lib/rutty/consts.rb",
39
- "lib/rutty/errors.rb",
40
- "lib/rutty/helpers.rb",
41
- "lib/rutty/node.rb",
42
- "lib/rutty/nodes.rb",
43
- "lib/rutty/proc_classes.rb",
44
- "lib/rutty/treetop/syntax_nodes.rb",
45
- "lib/rutty/treetop/tag_query.rb",
46
- "lib/rutty/treetop/tag_query.treetop",
47
- "lib/rutty/version.rb",
48
- "rutty.gemspec",
49
- "test/helper.rb",
50
- "test/test_action_add_node.rb",
51
- "test/test_action_dsh.rb",
52
- "test/test_action_init.rb",
53
- "test/test_action_list_nodes.rb",
54
- "test/test_actions.rb",
55
- "test/test_config.rb",
56
- "test/test_consts.rb",
57
- "test/test_helpers.rb",
58
- "test/test_node.rb",
59
- "test/test_nodes.rb",
60
- "test/test_runner.rb"
26
+ ".yardopts",
27
+ "Gemfile",
28
+ "Gemfile.lock",
29
+ "LICENSE",
30
+ "README.md",
31
+ "Rakefile",
32
+ "VERSION",
33
+ "bin/rutty",
34
+ "lib/rutty.rb",
35
+ "lib/rutty/actions.rb",
36
+ "lib/rutty/config.rb",
37
+ "lib/rutty/consts.rb",
38
+ "lib/rutty/errors.rb",
39
+ "lib/rutty/helpers.rb",
40
+ "lib/rutty/node.rb",
41
+ "lib/rutty/nodes.rb",
42
+ "lib/rutty/proc_classes.rb",
43
+ "lib/rutty/thread_pool/pool.rb",
44
+ "lib/rutty/thread_pool/worker.rb",
45
+ "lib/rutty/treetop/syntax_nodes.rb",
46
+ "lib/rutty/treetop/tag_query.rb",
47
+ "lib/rutty/treetop/tag_query.treetop",
48
+ "lib/rutty/version.rb",
49
+ "rutty.gemspec",
50
+ "test/helper.rb",
51
+ "test/test_action_add_node.rb",
52
+ "test/test_action_dsh.rb",
53
+ "test/test_action_init.rb",
54
+ "test/test_action_list_nodes.rb",
55
+ "test/test_action_scp.rb",
56
+ "test/test_actions.rb",
57
+ "test/test_config.rb",
58
+ "test/test_consts.rb",
59
+ "test/test_helpers.rb",
60
+ "test/test_node.rb",
61
+ "test/test_nodes.rb",
62
+ "test/test_runner.rb"
61
63
  ]
62
64
  s.homepage = %q{http://github.com/jlindsey/rutty}
63
- s.rdoc_options = ["--charset=UTF-8"]
65
+ s.licenses = ["MIT"]
64
66
  s.require_paths = ["lib"]
65
67
  s.rubygems_version = %q{1.3.7}
66
68
  s.summary = %q{A DSH implementation in Ruby}
67
69
  s.test_files = [
68
70
  "test/helper.rb",
69
- "test/test_action_add_node.rb",
70
- "test/test_action_dsh.rb",
71
- "test/test_action_init.rb",
72
- "test/test_action_list_nodes.rb",
73
- "test/test_actions.rb",
74
- "test/test_config.rb",
75
- "test/test_consts.rb",
76
- "test/test_helpers.rb",
77
- "test/test_node.rb",
78
- "test/test_nodes.rb",
79
- "test/test_runner.rb"
71
+ "test/test_action_add_node.rb",
72
+ "test/test_action_dsh.rb",
73
+ "test/test_action_init.rb",
74
+ "test/test_action_list_nodes.rb",
75
+ "test/test_action_scp.rb",
76
+ "test/test_actions.rb",
77
+ "test/test_config.rb",
78
+ "test/test_consts.rb",
79
+ "test/test_helpers.rb",
80
+ "test/test_node.rb",
81
+ "test/test_nodes.rb",
82
+ "test/test_runner.rb"
80
83
  ]
81
84
 
82
85
  if s.respond_to? :specification_version then
@@ -84,39 +87,87 @@ Gem::Specification.new do |s|
84
87
  s.specification_version = 3
85
88
 
86
89
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
90
+ s.add_runtime_dependency(%q<commander>, ["~> 4.0.3"])
91
+ s.add_runtime_dependency(%q<terminal-table>, ["~> 1.4.2"])
92
+ s.add_runtime_dependency(%q<json>, ["~> 1.4.6"])
93
+ s.add_runtime_dependency(%q<net-ssh>, ["~> 2.0.23"])
94
+ s.add_runtime_dependency(%q<net-scp>, ["~> 1.0.4"])
95
+ s.add_runtime_dependency(%q<builder>, ["~> 2.1.2"])
96
+ s.add_runtime_dependency(%q<treetop>, ["~> 1.4.8"])
97
+ s.add_runtime_dependency(%q<fastthread>, ["~> 1.0.7"])
98
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
99
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
100
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
101
+ s.add_development_dependency(%q<rcov>, [">= 0"])
102
+ s.add_development_dependency(%q<xml-simple>, ["~> 1.0.12"])
103
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
87
104
  s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
88
- s.add_development_dependency(%q<jeweler>, [">= 1.4.0"])
105
+ s.add_development_dependency(%q<jeweler>, [">= 1.5.1"])
89
106
  s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
90
107
  s.add_development_dependency(%q<xml-simple>, [">= 1.0.12"])
91
108
  s.add_runtime_dependency(%q<commander>, [">= 4.0.3"])
92
109
  s.add_runtime_dependency(%q<terminal-table>, [">= 1.4.2"])
110
+ s.add_runtime_dependency(%q<json>, [">= 1.4.6"])
93
111
  s.add_runtime_dependency(%q<net-ssh>, [">= 2.0.23"])
94
112
  s.add_runtime_dependency(%q<net-scp>, [">= 1.0.4"])
95
113
  s.add_runtime_dependency(%q<builder>, [">= 2.1.2"])
96
114
  s.add_runtime_dependency(%q<treetop>, [">= 1.4.8"])
115
+ s.add_runtime_dependency(%q<fastthread>, [">= 1.0.7"])
97
116
  else
117
+ s.add_dependency(%q<commander>, ["~> 4.0.3"])
118
+ s.add_dependency(%q<terminal-table>, ["~> 1.4.2"])
119
+ s.add_dependency(%q<json>, ["~> 1.4.6"])
120
+ s.add_dependency(%q<net-ssh>, ["~> 2.0.23"])
121
+ s.add_dependency(%q<net-scp>, ["~> 1.0.4"])
122
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
123
+ s.add_dependency(%q<treetop>, ["~> 1.4.8"])
124
+ s.add_dependency(%q<fastthread>, ["~> 1.0.7"])
125
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
126
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
127
+ s.add_dependency(%q<shoulda>, [">= 0"])
128
+ s.add_dependency(%q<rcov>, [">= 0"])
129
+ s.add_dependency(%q<xml-simple>, ["~> 1.0.12"])
130
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
98
131
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
99
- s.add_dependency(%q<jeweler>, [">= 1.4.0"])
132
+ s.add_dependency(%q<jeweler>, [">= 1.5.1"])
100
133
  s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
101
134
  s.add_dependency(%q<xml-simple>, [">= 1.0.12"])
102
135
  s.add_dependency(%q<commander>, [">= 4.0.3"])
103
136
  s.add_dependency(%q<terminal-table>, [">= 1.4.2"])
137
+ s.add_dependency(%q<json>, [">= 1.4.6"])
104
138
  s.add_dependency(%q<net-ssh>, [">= 2.0.23"])
105
139
  s.add_dependency(%q<net-scp>, [">= 1.0.4"])
106
140
  s.add_dependency(%q<builder>, [">= 2.1.2"])
107
141
  s.add_dependency(%q<treetop>, [">= 1.4.8"])
142
+ s.add_dependency(%q<fastthread>, [">= 1.0.7"])
108
143
  end
109
144
  else
145
+ s.add_dependency(%q<commander>, ["~> 4.0.3"])
146
+ s.add_dependency(%q<terminal-table>, ["~> 1.4.2"])
147
+ s.add_dependency(%q<json>, ["~> 1.4.6"])
148
+ s.add_dependency(%q<net-ssh>, ["~> 2.0.23"])
149
+ s.add_dependency(%q<net-scp>, ["~> 1.0.4"])
150
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
151
+ s.add_dependency(%q<treetop>, ["~> 1.4.8"])
152
+ s.add_dependency(%q<fastthread>, ["~> 1.0.7"])
153
+ s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
154
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
155
+ s.add_dependency(%q<shoulda>, [">= 0"])
156
+ s.add_dependency(%q<rcov>, [">= 0"])
157
+ s.add_dependency(%q<xml-simple>, ["~> 1.0.12"])
158
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
110
159
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
111
- s.add_dependency(%q<jeweler>, [">= 1.4.0"])
160
+ s.add_dependency(%q<jeweler>, [">= 1.5.1"])
112
161
  s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
113
162
  s.add_dependency(%q<xml-simple>, [">= 1.0.12"])
114
163
  s.add_dependency(%q<commander>, [">= 4.0.3"])
115
164
  s.add_dependency(%q<terminal-table>, [">= 1.4.2"])
165
+ s.add_dependency(%q<json>, [">= 1.4.6"])
116
166
  s.add_dependency(%q<net-ssh>, [">= 2.0.23"])
117
167
  s.add_dependency(%q<net-scp>, [">= 1.0.4"])
118
168
  s.add_dependency(%q<builder>, [">= 2.1.2"])
119
169
  s.add_dependency(%q<treetop>, [">= 1.4.8"])
170
+ s.add_dependency(%q<fastthread>, [">= 1.0.7"])
120
171
  end
121
172
  end
122
173