Skip to content

Commit

Permalink
(FACT-2753) Resolve facts sequentially.
Browse files Browse the repository at this point in the history
  • Loading branch information
BogdanIrimie committed Aug 31, 2020
1 parent b9f94b4 commit bab0e66
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 12 deletions.
11 changes: 11 additions & 0 deletions acceptance/tests/options/parallel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
test_name "--parallel argument does not generate any errors" do
tag 'risk:high'

agents.each do |agent|
step "--parallel should generate no errors" do
on(agent, facter("--parallel --debug"), :acceptable_exit_codes => 0) do |facter_output|
assert_match(/Resolving fact in parallel/, facter_output.stderr, "Resolving facts in parallel")
end
end
end
end
1 change: 1 addition & 0 deletions facter.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'sys-filesystem', '~> 1.3'
spec.add_development_dependency 'yard', '~> 0.9'

spec.add_runtime_dependency 'concurrent-ruby'
spec.add_runtime_dependency 'hocon', '~> 1.3'
spec.add_runtime_dependency 'thor', ['>= 1.0.1', '< 2.0']
end
12 changes: 12 additions & 0 deletions lib/facter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ def debugging(debug_bool)
Facter::Options[:debug] = debug_bool
end

def enable_parallel
Facter::Options[:parallel] = true
end

def disable_parallel
Facter::Options[:parallel] = false
end

def parallel?
Facter::Options[:parallel]
end

# Returns a fact object by name. If you use this, you still have to
# call {Facter::Util::Fact#value `value`} on it to retrieve the actual
# value.
Expand Down
4 changes: 4 additions & 0 deletions lib/facter/framework/cli/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ class Cli < Thor
aliases: '-p',
desc: 'Load the Puppet libraries, thus allowing Facter to load Puppet-specific facts.'

class_option :parallel,
type: :boolean,
desc: 'Resolve facts in parallel'

desc '--man', 'Manual', hide: true
map ['--man'] => :man
def man(*args)
Expand Down
2 changes: 1 addition & 1 deletion lib/facter/framework/core/fact/internal/core_fact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def initialize(searched_fact)
def create
fact_class = @searched_fact.fact_class

fact_class.new.call_the_resolver
fact_class&.new&.call_the_resolver
end
end
end
66 changes: 57 additions & 9 deletions lib/facter/framework/core/fact/internal/internal_fact_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@ class InternalFactManager

def resolve_facts(searched_facts)
internal_searched_facts = filter_internal_facts(searched_facts)
threads = start_threads(internal_searched_facts)
resolved_facts = join_threads(threads, internal_searched_facts)

resolved_facts = if Options[:parallel]
@@log.debug('Resolving fact in parallel')
threads = start_threads(internal_searched_facts)
join_threads(threads, internal_searched_facts)
# thread_pool(internal_searched_facts)
else
@@log.debug('Resolving facts sequentially')
resolve_sequentially(internal_searched_facts)
end

nil_resolved_facts = resolve_nil_facts(searched_facts)

Expand All @@ -29,20 +37,33 @@ def resolve_nil_facts(searched_facts)
resolved_facts
end

def resolve_sequentially(searched_facts)
resolved_facts = []

searched_facts
.uniq { |searched_fact| searched_fact.fact_class.name }
.each do |searched_fact|
begin
fact = CoreFact.new(searched_fact)
fact_value = fact.create
resolved_facts << fact_value unless fact_value.nil?
rescue StandardError => e
@@log.log_exception(e)
end
end

resolved_facts.flatten!
FactAugmenter.augment_resolved_facts(searched_facts, resolved_facts)
end

def start_threads(searched_facts)
threads = []
# only resolve a fact once, even if multiple search facts depend on that fact
searched_facts
.uniq { |searched_fact| searched_fact.fact_class.name }
.each do |searched_fact|
threads << Thread.new do
begin
fact = CoreFact.new(searched_fact)
fact.create
rescue StandardError => e
@@log.log_exception(e)
nil
end
resolve_fact(searched_fact)
end
end

Expand All @@ -61,5 +82,32 @@ def join_threads(threads, searched_facts)

FactAugmenter.augment_resolved_facts(searched_facts, resolved_facts)
end

def thread_pool(searched_facts)
require 'concurrent'

pool = Concurrent::FixedThreadPool.new(12)
pr_futures = []

searched_facts
.uniq { |searched_fact| searched_fact.fact_class.name }
.each do |searched_fact|
pr_futures << Concurrent::Promises.future_on(pool) do
resolve_fact(searched_fact)
end
end

resolved_facts = Concurrent::Promises.zip(*pr_futures).value!.flatten.compact

FactAugmenter.augment_resolved_facts(searched_facts, resolved_facts)
end

def resolve_fact(searched_fact)
fact = CoreFact.new(searched_fact)
fact.create
rescue StandardError => e
@@log.log_exception(e)
nil
end
end
end
4 changes: 3 additions & 1 deletion lib/facter/framework/core/options/option_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class OptionStore
@block_list = {}
@fact_groups = {}
@color = false
@parallel = false

class << self
attr_reader :debug, :verbose, :log_level, :show_legacy, :ruby,
Expand All @@ -31,7 +32,7 @@ class << self
attr_accessor :config, :user_query, :strict, :json, :haml, :external_facts,
:cache, :yaml, :puppet, :ttls, :block, :cli, :config_file_custom_dir,
:config_file_external_dir, :default_external_dir, :fact_groups,
:block_list, :color, :trace
:block_list, :color, :trace, :parallel

attr_writer :external_dir

Expand Down Expand Up @@ -159,6 +160,7 @@ def reset_config
@blocked_facts = []
@fact_groups = {}
@block_list = {}
@parallel = false
end

def fallback_external_dir
Expand Down
3 changes: 2 additions & 1 deletion spec/framework/core/options/option_store_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
config: nil,
cache: true,
color: false,
trace: false
trace: false,
parallel: false
)
end
end
Expand Down

0 comments on commit bab0e66

Please sign in to comment.