Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Batch limit seed #43

Closed
wants to merge 3 commits into from

2 participants

@phobos182

Added srand() to provide a deterministic way to generate random numbers. Use case documented here.

https://projects.puppetlabs.com/issues/14960

This will allow us to run subsequent commands to the same random set of hosts using a seeded value. Example: Run agent on 5% of discovered nodes with a seed. Then I can run calls on the same hosts using the same seed number as long as the number of discovered hosts does not change (That is important, state is wrapped up in the # of discovered hosts).

@ripienaar ripienaar closed this
@ripienaar

merged after some tweaking to work around a bug in the original code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 14 additions and 1 deletion.
  1. +10 −1 lib/mcollective/rpc/client.rb
  2. +4 −0 lib/mcollective/rpc/helpers.rb
View
11 lib/mcollective/rpc/client.rb
@@ -4,7 +4,7 @@ module RPC
# and just brings in a lot of convention and standard approached.
class Client
attr_accessor :timeout, :verbose, :filter, :config, :progress, :ttl, :reply_to
- attr_reader :client, :stats, :ddl, :agent, :limit_targets, :limit_method, :output_format, :batch_size, :batch_sleep_time, :batch_mode
+ attr_reader :client, :stats, :ddl, :agent, :limit_targets, :limit_method, :output_format, :batch_size, :batch_sleep_time, :limit_seed, :batch_mode
attr_reader :discovery_options, :discovery_method
@@initial_options = nil
@@ -49,6 +49,7 @@ def initialize(agent, flags = {})
@progress = initial_options[:progress_bar]
@limit_targets = initial_options[:mcollective_limit_targets]
@limit_method = Config.instance.rpclimitmethod
+ @limit_seed = initial_options[:limit_seed] || nil
@output_format = initial_options[:output_format] || :console
@force_direct_request = false
@reply_to = initial_options[:reply_to]
@@ -595,8 +596,11 @@ def batch_sleep_time=(time)
# - :first would be a simple way to do a distance based
# selection
# - anything else will just pick one at random
+ # - if random chosen, and batch-seed set, then set srand
+ # for the generator, and reset afterwards
def pick_nodes_from_discovered(count)
if count =~ /%$/
+ srand(@limit_seed) unless @limit_seed.nil?
pct = (discover.size * (count.to_f / 100)).to_i
pct == 0 ? count = 1 : count = pct
else
@@ -610,6 +614,7 @@ def pick_nodes_from_discovered(count)
if @limit_method == :first
return discover[0, count]
else
+ discover.sort!
count.times do
rnd = rand(discover.size)
result << discover[rnd]
@@ -617,6 +622,10 @@ def pick_nodes_from_discovered(count)
end
end
+ # Reset random number generator to fresh seed
+ # As our seed from options is most likely short
+ srand() unless @limit_seed.nil?
+
[result].flatten
end
View
4 lib/mcollective/rpc/helpers.rb
@@ -295,6 +295,10 @@ def self.add_simplerpc_options(parser, options)
options[:batch_sleep_time] = v
end
+ parser.on('--limit-seed NUMBER', Integer, 'Seed value for deterministic random batching') do |v|
+ options[:limit_seed] = v
+ end
+
parser.on('--limit-nodes COUNT', '--ln', 'Send request to only a subset of nodes, can be a percentage') do |v|
raise "Invalid limit specified: #{v} valid limits are /^\d+%*$/" unless v =~ /^\d+%*$/
Something went wrong with that request. Please try again.