Class: LyberCore::Robot

Inherits:
Object
  • Object
show all
Includes:
Sidekiq::Job
Defined in:
lib/lyber_core/robot.rb

Overview

Base class for all robots. Subclasses should implement the #perform_work method. To enable retries provide the retriable exceptions in the initializer.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(workflow_name, process, check_queued_status: true, retriable_exceptions: []) ⇒ Robot

Returns a new instance of Robot.



32
33
34
35
36
37
# File 'lib/lyber_core/robot.rb', line 32

def initialize(workflow_name, process, check_queued_status: true, retriable_exceptions: [])
  @workflow_name = workflow_name
  @process = process
  @check_queued_status = check_queued_status
  @retriable_exceptions = retriable_exceptions
end

Instance Attribute Details

#check_queued_statusObject

Returns the value of attribute check_queued_status.



24
25
26
# File 'lib/lyber_core/robot.rb', line 24

def check_queued_status
  @check_queued_status
end

#druidObject (readonly)

Returns the value of attribute druid.



23
24
25
# File 'lib/lyber_core/robot.rb', line 23

def druid
  @druid
end

#processObject (readonly)

Returns the value of attribute process.



23
24
25
# File 'lib/lyber_core/robot.rb', line 23

def process
  @process
end

#retriable_exceptionsObject (readonly)

Returns the value of attribute retriable_exceptions.



23
24
25
# File 'lib/lyber_core/robot.rb', line 23

def retriable_exceptions
  @retriable_exceptions
end

#versionObject (readonly)

Returns the value of attribute version.



23
24
25
# File 'lib/lyber_core/robot.rb', line 23

def version
  @version
end

#workflow_nameObject (readonly)

Returns the value of attribute workflow_name.



23
24
25
# File 'lib/lyber_core/robot.rb', line 23

def workflow_name
  @workflow_name
end

Instance Method Details

#bare_druidObject



109
110
111
# File 'lib/lyber_core/robot.rb', line 109

def bare_druid
  @bare_druid = druid.delete_prefix('druid:')
end

#cocina_objectObject



43
44
45
# File 'lib/lyber_core/robot.rb', line 43

def cocina_object
  @cocina_object ||= object_client.find
end

#druid_objectObject



47
48
49
# File 'lib/lyber_core/robot.rb', line 47

def druid_object
  @druid_object ||= DruidTools::Druid.new(druid, Settings.stacks.local_workspace_root)
end

#object_clientObject



39
40
41
# File 'lib/lyber_core/robot.rb', line 39

def object_client
  @object_client ||= Dor::Services::Client.object(druid)
end

#perform(druid, version = nil) ⇒ Object

Sets up logging, timing and error handling of the job Calls the #perform_work method, then sets workflow to 'completed' or 'error' depending on success rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
# File 'lib/lyber_core/robot.rb', line 55

def perform(druid, version = nil)
  @druid = druid
  @version = version
  Honeybadger.context(druid:, process:, workflow_name:)

  logger.info "#{druid} processing #{process} (#{workflow_name})"
  return skip_for_superseded_version! if superseded_version?
  return unless check_item_queued_or_retry?

  # this is the default note to pass back to workflow service,
  # but it can be overriden by a robot that uses the Robots::ReturnState
  # object to return a status
  note = Socket.gethostname

  # update the workflow status to indicate that started
  workflow.start!(note)

  result = nil
  elapsed = Benchmark.realtime do
    result = perform_work
  end

  # the final workflow state is determined by the return value of the perform step, if it is a ReturnState object,
  # we will use the defined status, otherwise default to completed
  # if a note is passed back, we will also use that instead of the default
  if result.instance_of?(ReturnState)
    workflow_state = result.status
    note = result.note unless result.note.blank?
  else
    workflow_state = 'completed'
  end
  # update the workflow status from its current state to the state returned by perform
  # (or 'completed' as the default)
  # noop allows a robot to not set a workflow as complete, e.g., if that is delegated to another service.
  workflow.complete!(workflow_state, elapsed, note) unless workflow_state == 'noop'

  logger.info "Finished #{druid} in #{format('%0.4f', elapsed)}s"
rescue *retriable_exceptions => e
  handle_error(e)
  workflow.retrying!
  raise
rescue StandardError => e
  handle_error(e)
  workflow.error!(e.message, Socket.gethostname)
end

#perform_workObject

Work performed by the robot. This method is to be implemented by robot subclasses.

Raises:

  • (NotImplementedError)


105
106
107
# File 'lib/lyber_core/robot.rb', line 105

def perform_work
  raise NotImplementedError
end