-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathbackground.rb
More file actions
62 lines (55 loc) · 2.22 KB
/
background.rb
File metadata and controls
62 lines (55 loc) · 2.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# frozen_string_literal: true
# Starts a block of code in parallel with the main plan without blocking.
# Returns a Future object.
#
# > **Note:** Not available in apply block
Puppet::Functions.create_function(:background, Puppet::Functions::InternalFunction) do
# Starts a block of code in parallel with the main plan without blocking.
# Returns a Future object.
# @param name An optional name for legible logs.
# @param block The code block to run in the background.
# @return A Bolt Future object
# @example Start a long-running process
# background() || {
# run_task('superlong::task', $targets)
# }
# run_command("echo 'Continue immediately'", $targets)
dispatch :background do
scope_param
optional_param 'String[1]', :name
block_param 'Callable[0, 0]', :block
return_type 'Future'
end
def background(scope, name = nil, &block)
unless Puppet[:tasks]
raise Puppet::ParseErrorWithIssue
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'background')
end
executor = Puppet.lookup(:bolt_executor)
executor.report_function_call(self.class.name)
plan_id = executor.get_current_plan_id(fiber: Fiber.current)
executor.create_future(scope: scope, name: name, plan_id: plan_id) do |newscope|
# Catch 'return' calls inside the block
result = catch(:return) do
# Execute the block. Individual plan steps in the block will yield
# the Fiber if they haven't finished, so all this needs to do is run
# the block.
block.closure.call_by_name_with_scope(newscope, {}, true)
end
# If we got a return from the block, get its value
# Otherwise the result is the last line from the block
result = result.value if result.is_a?(Puppet::Pops::Evaluator::Return)
# Validate the result is a PlanResult
unless Puppet::Pops::Types::TypeParser.singleton.parse('Boltlib::PlanResult').instance?(result)
raise Bolt::InvalidParallelResult.new(result.to_s, *Puppet::Pops::PuppetStack.top_of_stack)
end
result
rescue Puppet::PreformattedError => e
if e.cause.is_a?(Bolt::Error)
e.cause
else
raise e
end
end
end
end