module Facter::Core::Resolvable

The resolvable mixin defines behavior for evaluating and returning fact resolutions.

Classes including this mixin should implement at name method describing the value being resolved and a resolve_value that actually executes the code to resolve the value.

Attributes

timeout[RW]

The timeout, in seconds, for evaluating this resolution. @return [Integer] @api public

Public Instance Methods

flush() click to toggle source

flush executes the block, if any, stored by the {on_flush} method

@see Facter::Util::Fact#flush @see #on_flush

@api private

# File lib/facter/core/resolvable.rb, line 54
def flush
  @on_flush_block.call if @on_flush_block
end
limit() click to toggle source

Return the timeout period for resolving a value. (see timeout) @return [Numeric] @comment requiring 'timeout' stdlib class causes Object#timeout to be

defined which delegates to Timeout.timeout. This method may potentially
overwrite the #timeout attr_reader on this class, so we define #limit to
avoid conflicts.
# File lib/facter/core/resolvable.rb, line 23
def limit
  @timeout || 0
end
on_flush(&block) click to toggle source

#on_flush accepts a block and executes the block when the resolution's value is flushed. This makes it possible to model a single, expensive system call inside of a Ruby object and then define multiple dynamic facts which resolve by sending messages to the model instance. If one of the dynamic facts is flushed then it can, in turn, flush the data stored in the model instance to keep all of the dynamic facts in sync without making multiple, expensive, system calls.

Please see the Solaris zones fact for an example of how this feature may be used.

@see Facter::Util::Fact#flush @see #flush

@api public

# File lib/facter/core/resolvable.rb, line 43
def on_flush(&block)
  @on_flush_block = block
end
value() click to toggle source
# File lib/facter/core/resolvable.rb, line 58
def value
  result = nil

  with_timing do
    Timeout.timeout(limit) do
      result = resolve_value
    end
  end

  Facter::Util::Normalization.normalize(result)
rescue Timeout::Error => detail
  Facter.log_exception(detail, "Timed out after #{limit} seconds while resolving #{qualified_name}")
  return nil
rescue Facter::Util::Normalization::NormalizationError => detail
  Facter.log_exception(detail, "Fact resolution #{qualified_name} resolved to an invalid value: #{detail.message}")
  return nil
rescue => detail
  Facter.log_exception(detail, "Could not retrieve #{qualified_name}: #{detail.message}")
  return nil
end

Private Instance Methods

qualified_name() click to toggle source
# File lib/facter/core/resolvable.rb, line 91
def qualified_name
  "fact='#{@fact.name.to_s}', resolution='#{@name || '<anonymous>'}'"
end
with_timing() { || ... } click to toggle source
# File lib/facter/core/resolvable.rb, line 81
def with_timing
  starttime = Time.now.to_f

  yield

  finishtime = Time.now.to_f
  ms = (finishtime - starttime) * 1000
  Facter.show_time "#{qualified_name}: #{"%.2f" % ms}ms"
end