Class: Roast::Cog

Inherits:
Object
  • Object
show all
Defined in:
lib/roast/cog.rb,
lib/roast/cog/input.rb,
lib/roast/cog/stack.rb,
lib/roast/cog/store.rb,
lib/roast/cog/config.rb,
lib/roast/cog/output.rb,
lib/roast/cog/registry.rb

Defined Under Namespace

Classes: CogAlreadyStartedError, CogError, Config, Input, Output, Registry, Stack, Store

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, cog_input_proc, anonymous: false) ⇒ Cog

: (Symbol, ^(Cog::Input) -> untyped, ?anonymous: bool) -> void



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/roast/cog.rb', line 48

def initialize(name, cog_input_proc, anonymous: false)
  @name = name
  @anonymous = anonymous
  @cog_input_proc = cog_input_proc #: ^(Cog::Input) -> untyped
  @output = nil #: Cog::Output?
  @skipped = false #: bool
  @failed = false #: bool

  # Make sure a config is always defined, so we don't have to worry about nils
  @config = self.class.config_class.new #: untyped
end

Instance Attribute Details

#nameObject (readonly)

: Symbol



42
43
44
# File 'lib/roast/cog.rb', line 42

def name
  @name
end

#outputObject (readonly)

: Cog::Output?



45
46
47
# File 'lib/roast/cog.rb', line 45

def output
  @output
end

Class Method Details

.config_classObject

: () -> singleton(Cog::Config)



12
13
14
# File 'lib/roast/cog.rb', line 12

def config_class
  @config_class ||= find_child_config_or_default
end

.generate_fallback_nameObject

: () -> Symbol



22
23
24
# File 'lib/roast/cog.rb', line 22

def generate_fallback_name
  Random.uuid.to_sym
end

.input_classObject

: () -> singleton(Cog::Input)



17
18
19
# File 'lib/roast/cog.rb', line 17

def input_class
  @input_class ||= find_child_input_or_default #: singleton(Cog::Input)?
end

Instance Method Details

#anonymous?Boolean

: () -> bool

Returns:

  • (Boolean)


61
62
63
# File 'lib/roast/cog.rb', line 61

def anonymous?
  @anonymous
end

#failed?Boolean

: () -> bool

Returns:

  • (Boolean)


122
123
124
# File 'lib/roast/cog.rb', line 122

def failed?
  @failed || !!@task&.failed?
end

#run!(barrier, config, input_context, executor_scope_value, executor_scope_index) ⇒ Object

: (Async::Barrier, Cog::Config, CogInputContext, untyped, Integer) -> Async::Task



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/roast/cog.rb', line 71

def run!(barrier, config, input_context, executor_scope_value, executor_scope_index)
  raise CogAlreadyStartedError if @task

  @task = barrier.async(finished: false) do |task|
    task.annotate("Cog #{type}(:#{@name})")
    TaskContext.begin_cog(self)
    @config = config
    input_instance = self.class.input_class.new
    input_return = input_context.instance_exec(
      input_instance, executor_scope_value, executor_scope_index, &@cog_input_proc
    ) if @cog_input_proc
    coerce_and_validate_input!(input_instance, input_return)
    @output = execute(input_instance)
  rescue ControlFlow::SkipCog
    # TODO: do something with the message passed to skip!
    @skipped = true
  rescue ControlFlow::FailCog => e
    # TODO: do something with the message passed to fail!
    @failed = true
    # TODO: better / cleaner handling in the workflow execution manager for a workflow failure
    #   just re-raising this exception for now
    raise e if config.abort_on_failure?
  rescue ControlFlow::Next, ControlFlow::Break => e
    @skipped = true
    raise e
  rescue StandardError => e
    @failed = true
    raise e
  ensure
    TaskContext.end
  end
end

#skipped?Boolean

: () -> bool

Returns:

  • (Boolean)


117
118
119
# File 'lib/roast/cog.rb', line 117

def skipped?
  @skipped
end

#started?Boolean

: () -> bool

Returns:

  • (Boolean)


112
113
114
# File 'lib/roast/cog.rb', line 112

def started?
  @task.present?
end

#stopped?Boolean

: () -> bool

Returns:

  • (Boolean)


127
128
129
# File 'lib/roast/cog.rb', line 127

def stopped?
  !!@task&.stopped?
end

#succeeded?Boolean

: () -> bool

Returns:

  • (Boolean)


132
133
134
135
136
# File 'lib/roast/cog.rb', line 132

def succeeded?
  # NOTE: explicitly checking `@output == nil` because the `ruby` cog's Output class delegates
  # all missing methods to its `value`, which may be nil when the Output object is actually present.
  @output != nil && @task&.finished? # rubocop:disable Style/NonNilCheck
end

#typeObject

: () -> String



66
67
68
# File 'lib/roast/cog.rb', line 66

def type
  self.class.name.not_nil!.demodulize.underscore
end

#waitObject

: () -> void



105
106
107
108
109
# File 'lib/roast/cog.rb', line 105

def wait
  @task&.wait
rescue
  # Do nothing if the cog's task raised an exception. That is handled elsewhere.
end