Class: UU::OS::REST::Future

Inherits:
Object
  • Object
show all
Defined in:
uu_os_framework-0.29.16/lib/uu/os/rest/future.rb

Overview

Object for accessing result of asynchronous processes.

Constant Summary

Instance Method Summary (collapse)

Constructor Details

- (Future) initialize(init_data, result_code = nil)

Creates new instance of Future.

Examples:

# init future from string
future1 = UU::OS::REST::Future.new('ues:[123]:[456]')

# init future from UESURI
proc_uri = UU::OS::UESURI.new('ues:[123]:[456]')
future1 = UU::OS::REST::Future.new(proc_uri)

# init future from another Future
future2 = UU::OS::REST::Future.new(future1)

# init future with default result code
future1 = UU::OS::REST::Future.new(proc_uri, 'EXPORT_RESULT')

Parameters:

  • init_data (String, UU::OS::UESURI, UU::OS::REST::Future)

    URI of asynchronous process where to look for result or another instance of Future.

  • resultCode (String)

    Default result code. This core is used when UESFuture.get is called without result code.



40
41
42
43
44
45
46
47
48
49
# File 'uu_os_framework-0.29.16/lib/uu/os/rest/future.rb', line 40

def initialize(init_data, result_code = nil)

  if init_data.kind_of?UU::OS::REST::Future
    @process_uri = init_data.get_process_uri
  else
    @process_uri = UU::OS::UESURI.new(init_data)
  end

  @default_result_code = result_code
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(method, *args, &block) (private)



192
193
194
195
196
197
198
199
200
201
202
203
# File 'uu_os_framework-0.29.16/lib/uu/os/rest/future.rb', line 192

def method_missing(method, *args, &block) #:nodoc:
  # Delegate unknown method calling to the inner UESURI object because of backward compatibility
  if @process_uri.respond_to? method
    # log warning
    logger.warning("Script tries to use method from the UESURI object on Future object. Method name: #{method}, Back trace: #{caller.join("\n")}")
    # send event to inner UESURI
    return @process_uri.send(method, *args, &block)
  else
    # if the method is not defined either on the UESURI object
    super
  end
end

Instance Method Details

- (UU::OS::UESURI) get(result_code = nil, timeout = 60)

Returns result identified by the given result_code.

Examples:


# init future object
future = UU::OS::REST::Future.new('ues:[123]:[456]')

# Get first available result of parent process in default timeout 1 minute,
# method returns nil if parent process ends with no result regardless of
# subprocesses, or raises exception if parent process fails.
result = future.get

# Same as above but timeout is 2 minutes.
result = future.get(120)

# Get result of event with code 'EXPORT_RESULT', search also all subprocess
# method returns nil if parent process or any subprocess do not set result
# with code 'EXPORT_RESULT'. Raises exception if event with given code is
# error event.
result = future.get('EXPORT_RESULT')

# Same as above but timeout is 2 minutes.
result = future.get('EXPORT_RESULT', 120)

Parameters:

  • result_code (String) (defaults to: nil)

    Code (regular expressions may be used) of the required result. Default is nil which means we are waiting for result of parent process final state. In case of explicitly given result_code result is being searched also in all nested (asynchronous) subprocesses. In case of nil value result is returned as soon as parent process is finished (does not wait and search for results of nested asynchronous subprocesses). Result code can be also specified in constructor. And this default value from constructor is used only when nil is passed as resultCode to this method.

  • timeout (Numeric) (defaults to: 60)

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

Returns:

  • (UU::OS::UESURI)

    Result in form of UESURI or nil if result was not provided. Throws exception in case the result has not been provided in the given timeout.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'uu_os_framework-0.29.16/lib/uu/os/rest/future.rb', line 85

def get(result_code = nil, timeout = 60)
  if result_code.kind_of?Numeric
    timeout = result_code
    result_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)
  result = nil
  svc = RemoteClient.new(UU::OS::REST, @@PROCEXP_PATH)
  
  # if result_code passed to method is null, try default result code from constructor
  result_code = @default_result_code if result_code.nil?
  
  if !result_code.nil?
    data = "{\"eventCodes\":[\"#{result_code}\"]}"
  else
    data = '{}'
  end
  while true
    result = svc.post(:getProcessResult, @process_uri, data)
    if (result == 'null') || (result == '')
      # Nil result is wrongly returned as "null" string or empty string
      # (based on process entity existence)
      result = nil
    end
    if (result)
      # Result object was provided (event matching given code or event
      # representing process final state if no explicit code is given)
      result = JSON.parse(result, :symbolize_names => true)
      if result_code.nil? && (result[:state] == 'FAILED' || result[:state] == 'ERROR')
        init_data = "{\"code\":\"UU.OS/E05P02.M16\",\"errorMessages\":[{\"code\":\"UU.OS/E05P02.M16\",\"localizedMessage\":\"Asynchronous process was not successfully finished:\\n\\t#{error_message(result)}\"}]}"
        raise UU::OS::REST::ServerException.new(init_data)
      elsif !result[:errorCode].nil?
        init_data = "{\"code\":\"UU.OS/E05P02.M16\",\"errorMessages\":[{\"code\":\"UU.OS/E05P02.M17\",\"localizedMessage\":\"Expected result cannot be provided:\\n\\t#{error_message(result)}\"}]}"
        raise UU::OS::REST::ServerException.new(init_data)
      elsif !result[:result].nil?
        # Get result UESURI
        result = UU::OS::UESURI.new(result[:result])
      else
        # No UESURI -> no result
        result = nil
      end
      break
    end
    status = JSON.parse(svc.get(:getProcessProgress, @process_uri), :symbolize_names => true)
    if status[:finished] >= 0
      # We have no result, but the process is finished
      break
    end
    if remaining_time <= 0
      # We have no result, process is not finished, but we are out of time
      raise 'Result has not been provided by process in the given time.'
    end
    # 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
  result
end

- (UU::OS::UESURI) get_process_uri

Returns underlining process uri.

Examples:

# get proces uri
proc_uri = future.get_process_uri

Returns:



163
164
165
# File 'uu_os_framework-0.29.16/lib/uu/os/rest/future.rb', line 163

def get_process_uri
  @process_uri
end

- (String) to_json(options = {})

Returns json representation of underlining process uri.

Examples:

# Json representation
future.to_json # String '"ues:[123]:[456]"'

Returns:

  • (String)


185
186
187
# File 'uu_os_framework-0.29.16/lib/uu/os/rest/future.rb', line 185

def to_json(options = {})
  @process_uri.to_json(options)
end

- (String) to_s

Returns string representation of underlining process uri.

Examples:

# String representation
future.to_s # String 'ues:[123]:[456]'

Returns:

  • (String)


174
175
176
# File 'uu_os_framework-0.29.16/lib/uu/os/rest/future.rb', line 174

def to_s
  @process_uri.to_s
end