Module: UU::OS::Env::Process

Extended by:
Process
Included in:
Process
Defined in:
uu_os_framework-0.29.16/lib/uu/os/env/process.rb,
uu_os_framework-0.29.16/lib/uu/os/env/process/process_run.rb,
uu_os_framework-0.29.16/lib/uu/os/env/process/process_event.rb,
uu_os_framework-0.29.16/lib/uu/os/env/process/process_result.rb,
uu_os_framework-0.29.16/lib/uu/os/env/process/process_message.rb,
uu_os_framework-0.29.16/lib/uu/os/env/process/process_event_type.rb

Overview

Provides operations for managing of process.

Defined Under Namespace

Classes: ProcessEvent, ProcessEventType, ProcessMessage, ProcessResult, ProcessRun

Instance Method Summary (collapse)

Instance Method Details

- (UU::OS::UESURI) active_process_uri

Returns URI of active process or nil if no process exists.

Returns:



83
84
85
86
87
88
89
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 83

def active_process_uri
  if Thread.current[@@PROCESS_PARAM]
    Thread.current[@@PROCESS_PARAM][-1]
  else
    nil
  end
end

- (Object) completed(message)

Method marks use case as completed. This state means use case is finished. Calling of this method is optional.

Parameters:



169
170
171
172
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 169

def completed(message)
  event_code = "COMPLETED_#{Time.now.to_f}"
  self.fire_completed_event(:event_type => UU::OS::Env::Process::ProcessEventType::COMPLETED, :event_code => event_code, :event_message => message)
end

- (Object) completed_with_error(message, exception = nil)

Method marks use case as failed. Failed state means there was some serious problem which is not covered by any alternative flow of use case. Calling of this method is optional. In case of exception thrown from use case, process automatically ends in failed state. This method can be uses to override default error message.

Parameters:

  • message (String, ProcessMessage)

    Message for user

  • exception (Exception) (defaults to: nil)

    Exception which caused problem (may be nil)



193
194
195
196
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 193

def completed_with_error(message, exception = nil)
  event_code = "COMPLETED_WITH_ERROR_#{Time.now.to_f}"
  self.fire_completed_event(:event_type => UU::OS::Env::Process::ProcessEventType::COMPLETED_WITH_ERROR, :event_code => event_code, :event_message => message, :exception => nil)
end

- (Object) completed_with_warning(message, exception = nil)

Method marks use case as completed with warnings. This state means use case is finished but due to some internal problems it did not provide expected result but ended up in some alternative flow. Calling of this method is optional.

Parameters:

  • message (String, ProcessMessage)

    Message for user

  • exception (Exception) (defaults to: nil)

    Exception which caused problem (may be nil)



181
182
183
184
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 181

def completed_with_warning(message, exception = nil)
  event_code = "COMPLETED_WITH_WARNING_#{Time.now.to_f}"
  self.fire_completed_event(:event_type => UU::OS::Env::Process::ProcessEventType::COMPLETED_WITH_WARNING, :event_code => event_code, :event_message => message, :exception => nil)
end

- (Object) fire_active_event(process_event)

Method is used for invocation of general active process event (alternative to using methods info, warning and progress). Unlike other methods, general event has more options. It allows to set code of event (which may be used by other processes as synchronization point) and UESURI of related object (used to provide partial result for processes waiting for this event).

Parameters:

  • process_event (ProcessEvent)

    DTO with event parameters



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 136

def fire_active_event(process_event)
  if self.active_process_uri.nil?
    raise 'There is no active process. This method should be called inside UU::OS::Env::Process.run block.'
  end
  if process_event.nil?
    raise ArgumentError.new('Event parameters are mandatory to fire new event.')
  end
  dto = UU::OS::Env::Process::ProcessEvent.new(process_event)
  if dto.event_type == UU::OS::Env::Process::ProcessEventType::ACTIVE_PROGRESS
    dto.event_type = 'PROGRESS'
    dto.send(:attributes)[:workedUnits] = 1
  elsif dto.event_type == UU::OS::Env::Process::ProcessEventType::ACTIVE_INFO
    dto.event_type = 'INFO'
    dto.send(:attributes)[:workedUnits] = 1
  elsif dto.event_type == UU::OS::Env::Process::ProcessEventType::ACTIVE_WARNING
    dto.event_type = 'WARNING'
    dto.send(:attributes)[:workedUnits] = 0
  else
    raise ArgumentError.new("Unsupported active event type #{dto.event_type}")
  end
  if dto.exception
    # TODO Remote process API should accept exception message instead of only error code
    dto.send(:attributes)[:errorCode] = dto.exception.message
    dto.exception = nil
  end
  svc = UU::OS::REST::RemoteClient.new(self, @@PC_PATH)
  svc.post(:fireEvent, self.active_process_uri, {:event => dto}.to_json)
end

- (Object) fire_completed_event(process_event)

Method is used for invocation of general completed process event (alternative to using methods completed, completed_with_warning and completed_with_error). Unlike other methods, general event has more options. It allows to set code of event (which may be used by other processes as synchronization point) and UESURI of related object (used to provide partial result for processes waiting for this event).

Parameters:

  • process_event (ProcessEvent)

    DTO with event parameters



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 205

def fire_completed_event(process_event)
  if self.active_process_uri.nil?
    raise 'There is no active process. This method should be called inside UU::OS::Env::Process.run block.'
  end
  if process_event.nil?
    raise ArgumentError.new('Event parameters are mandatory to fire new event.')
  end
  dto = UU::OS::Env::Process::ProcessEvent.new(process_event)
  if dto.event_type == UU::OS::Env::Process::ProcessEventType::COMPLETED
    exit_state = 'FINISHED'
    dto.send(:attributes)[:workedUnits] = 0
  elsif dto.event_type == UU::OS::Env::Process::ProcessEventType::COMPLETED_WITH_WARNING
    exit_state = 'FAILED'
    dto.send(:attributes)[:workedUnits] = 0
  elsif dto.event_type == UU::OS::Env::Process::ProcessEventType::COMPLETED_WITH_ERROR
    exit_state = 'ERROR'
    dto.send(:attributes)[:workedUnits] = 0
  else
    raise ArgumentError.new("Unsupported completed event type #{dto.event_type}")
  end
  if dto.exception
    # TODO Remote process API should accept exception message instead of only error code
    dto.send(:attributes)[:errorCode] = dto.exception.message
    dto.exception = nil
  end
  svc = UU::OS::REST::RemoteClient.new(self, @@PC_PATH)
  svc.post(:done, self.active_process_uri, {:exitState => exit_state, :event => dto}.to_json)
end

- (ProcessResult) get_result(event_code = nil, timeout = 60)

Deprecated.

This method has been deprecated. Use REST::Future#get instead.

Method searches all subprocesses of recent use case process and returns first result matching provided event code within given timeout. In case no event code is given, method waits until all subprocesses are finished and returns result with UESURI of related object from last finished process (result which was set in last finished subprocess, if non is present, result from previously finished subprocess, etc.). Method waits for result until matching event is invoked from any subprocess, timeout expires or all subprocesses are finished (meaning expected event cannot be set anymore).

Parameters:

  • event_code (String) (defaults to: nil)

    Event code (regular expressions may be used)

  • timeout (Numeric) (defaults to: 60)

    Maximum wait time in seconds (default is one minute, maximum is 30 minutes)

Returns:

  • (ProcessResult)

    First found result matching event code or last result from all subprocesses if event code is not provided.



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 250

def get_result(event_code = nil, timeout = 60)
  if self.active_process_uri.nil?
    raise 'There is no active process. Either use this method inside UU::OS::Env::Process.run block or use UU::OS::REST::Future instead.'
  end
  if (event_code.kind_of?Numeric)
    # Reassign parameters if only timeout was given
    timeout = event_code
    event_code = nil
  end
  if (timeout < 0) || (timeout > @@MAXIMUM_WAIT_TIMEOUT)
    remaining_time = @@MAXIMUM_WAIT_TIMEOUT
  else
    remaining_time = timeout
  end
  wait = 0.5 # First wait will be one second (in each loop value is multiplied by 2)
  svc = UU::OS::REST::RemoteClient.new(UU::OS::REST, @@PE_PATH)
  svc.add_parameter(:recursive, false)
  if event_code
    dto = "{\"eventCodes\":[\"#{event_code}\"]}"
  else
    dto = "{\"eventCodes\":[]}"
  end
  last_result = nil
  last_result_time = 0
  while true
    wait_finished = true
    # Get all direct subprocesses
    process_list = JSON.parse(svc.get(:getProcessList, self.active_process_uri), :symbolize_names => true)
    if !process_list[:pageEntries].nil?
      process_list[:pageEntries].each do |process|
        # Get subprocess result (either final result or result matching event code)
        result = svc.post(:getProcessResult, process[:uri], dto)
        if (result == 'null') || (result == '')
          # Nil result is wrongly returned as "null" string or empty string
          # (based on process entity existence)
          result = nil
        else
          result = UU::OS::Env::Process::ProcessResult.new(result)
        end
        if (result) && (!event_code)
          # Event code is not set - we are waiting for finishing of all subprocesses
          # If subprocess was finished as latest and contains result UESURI store its result
          state = svc.get(:getProcessProgress, process[:uri])
          state = JSON.parse(state, :symbolize_names => true)
          # If we have no result yet...
          if (!last_result) ||
          # ...or latest result has no UESURI and recent result either has UESURI or is newer...
          ((!last_result.result) && ((result.result) || (state[:finished] > last_result_time))) ||
          # ...or recent result is newer and has also UESURI...
          ((result.result) && (state[:finished] > last_result_time))
            # ...store recent result
            last_result_time = state[:finished]
            last_result = result
          end
        elsif (result)
          # Codes were set - we are waiting for concrete result. In case we have it, return immediately.
          return result;
        elsif (wait_finished)
          # Result of recent process is null and all previous subprocesses were finished. Check if recent
          # process is also finished in order to interrupt unnecessary waiting
          state = svc.get(:getProcessProgress, process[:uri])
          state = JSON.parse(state, :symbolize_names => true)
          wait_finished = (state[:finished] > 0)
        end
      end
    end
    if (wait_finished)
      # Wait was finished, return latest result. This branch can be called only if we are waiting for finishing of
      # all subprocesses or all process were finished and thus we cannot obtain expected result (lastResult is null
      # in this case).
      return last_result
    elsif (remaining_time <= 0)
      # Waiting is over, we do not have expected result
      return nil
    else
      # Wait longer in each cycle (in order not to flood remote server)
      wait *= 2
      if (remaining_time > wait)
        remaining_time -= wait
      else
        # If next wait is greater than remaining wait time, wait for the remaining time only
        wait = remaining_time
        remaining_time = 0
      end
      sleep(wait.to_i)
    end
  end
end

- (Object) info(message)

Method send info notification from use case. Unlike common messages (send by progress method) which is stored directly on recent process, notification is propagated further into other components and may trigger additional actions. Therefore notification should be used only for reporting of important milestones in use case flow. In case detailed reporting was enabled (total_steps were set in run block), each call of info notification means one step.

Parameters:



99
100
101
102
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 99

def info(message)
  event_code = "INFO_#{Time.now.to_f}"
  self.fire_active_event(:event_type => UU::OS::Env::Process::ProcessEventType::ACTIVE_INFO, :event_code => event_code, :event_message => message)
end

- (Object) progress(message)

Method is used for informing user of use case progress. Unlike notifications, progress message is stored directly on process and is not propagated into other components. In case detailed reporting was enabled (total_steps were set in run block), each call of progress method means one step.

Parameters:



124
125
126
127
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 124

def progress(message)
  event_code = "PROGRESS_#{Time.now.to_f}"
  self.fire_active_event(:event_type => UU::OS::Env::Process::ProcessEventType::ACTIVE_PROGRESS, :event_code => event_code, :event_message => message)
end

- (Object) run(use_case_uri, params = nil, &block)

Provides block wrapped by process.

Examples:

Usage:

UU::OS::Env::Process.run('ues:SYS:SOME_UC', :main_entity_uri => 'ues:UNI:SOME_ARTIFACT') do
  ...
end

Parameters:

  • use_case_uri (String, UU::OS::UESURI)

    URI of use case for which process is created

  • params (ProcessRun) (defaults to: nil)

    DTO with additional process parameters

  • block (Proc)

    Code to be executed inside process



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 46

def run(use_case_uri, params = nil, &block)
  # Create new process...
  svc = UU::OS::REST::RemoteClient.new(self, @@PC_PATH)
  dto = ProcessRun.new(params)
  dto.parent_process_uri = active_process_uri if !dto.parent_process_uri
  push_process(UU::OS::UESURI.new(svc.post(:create, use_case_uri, dto.to_json)))
  # ...and start it
  svc = UU::OS::REST::RemoteClient.new(self, @@PC_PATH)
  dto.message = nil # Message from DTO was used for "create" operation
  process_uri = active_process_uri
  svc.post(:start, process_uri, dto.to_json)
  error = nil
  begin
    # Call block of code representing process workload
    block.call
  rescue Exception => e
    error = e
  ensure
    if !error
      # Process was finished
      svc = UU::OS::REST::RemoteClient.new(self, @@PC_PATH)
      dto = {:exitState => 'FINISHED'}
      svc.post(:release, pop_process, dto.to_json)
    else
      # Process failed
      svc = UU::OS::REST::RemoteClient.new(self, @@PC_PATH)
      dto = {:exitState => 'ERROR', :event => {:eventType => 'WARNING', :eventMessage => {:message => "Process failed: #{error.message}"}}}
      svc.post(:release, pop_process, dto.to_json)
      raise error
    end
  end
  return UU::OS::REST::Future.new(process_uri)
end

- (Object) warning(message, exception = nil)

Method send warning notification from use case. Unlike common messages (send by progress method) which is stored directly on recent process, notification is propagated further into other components and may trigger additional actions. Therefore warning notification should be used only for reporting of more serious problems in use case flow. In case detailed reporting was enabled (total_steps were set in run block), call of warning notification has no effect (progress is not pushed further).

Parameters:

  • message (String, ProcessMessage)

    Message for user

  • exception (Exception) (defaults to: nil)

    Exception which caused problem (may be nil)



113
114
115
116
# File 'uu_os_framework-0.29.16/lib/uu/os/env/process.rb', line 113

def warning(message, exception = nil)
  event_code = "WARNING_#{Time.now.to_f}"
  self.fire_active_event(:event_type => UU::OS::Env::Process::ProcessEventType::ACTIVE_WARNING, :event_code => event_code, :event_message => message, :exception => exception)
end