Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Batch limit seed #43

wants to merge 3 commits into from

2 participants


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

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

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
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
@@ -610,6 +614,7 @@ def pick_nodes_from_discovered(count)
if @limit_method == :first
return discover[0, count]
+ discover.sort!
count.times do
rnd = rand(discover.size)
result << discover[rnd]
@@ -617,6 +622,10 @@ def pick_nodes_from_discovered(count)
+ # Reset random number generator to fresh seed
+ # As our seed from options is most likely short
+ srand() unless @limit_seed.nil?
4 lib/mcollective/rpc/helpers.rb
@@ -295,6 +295,10 @@ def self.add_simplerpc_options(parser, options)
options[:batch_sleep_time] = v
+ 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.