Class: StateFlow::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/state_flow/context.rb

Defined Under Namespace

Classes: Manipulation

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(flow, record, options = nil) ⇒ Context

Returns a new instance of Context.



7
8
9
10
11
12
13
# File 'lib/state_flow/context.rb', line 7

def initialize(flow, record, options = nil)
  @flow, @record = flow, record
  @options = {
    :save => :save!,
    :keep_process => true
  }.update(options || {})
end

Instance Attribute Details

#flowObject (readonly)

Returns the value of attribute flow.



5
6
7
# File 'lib/state_flow/context.rb', line 5

def flow
  @flow
end

#optionsObject (readonly)

Returns the value of attribute options.



5
6
7
# File 'lib/state_flow/context.rb', line 5

def options
  @options
end

#recordObject (readonly)

Returns the value of attribute record.



5
6
7
# File 'lib/state_flow/context.rb', line 5

def record
  @record
end

Instance Method Details

#current_attr_keyObject



183
184
185
# File 'lib/state_flow/context.rb', line 183

def current_attr_key
  record_send(flow.attr_key_name)
end

#exceptionsObject



171
172
173
# File 'lib/state_flow/context.rb', line 171

def exceptions
  @exceptions ||= []
end

#finish_force_recoveringObject



80
# File 'lib/state_flow/context.rb', line 80

def finish_force_recovering; @force_recovering = false; end

#force_recovering?Boolean

Returns:

  • (Boolean)


81
# File 'lib/state_flow/context.rb', line 81

def force_recovering?; @force_recovering; end

#log_with_stack_trace(level, *messages) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/state_flow/context.rb', line 99

def log_with_stack_trace(level, *messages)
  options = messages.extract_options!
  exception = options.delete(:exception)
  backtrace = options.delete(:backtrace)
  result = "#{messages.shift}"
  result << "\n  exception: #{exception.inspect}" if exception
  messages.each do |msg|
    result << "\n  #{msg}"
  end
  options.each do |key, value|
    result << "\n  #{key.inspect}: #{value.inspect}"
  end
  if exception && backtrace
    result << "\n  exception.backtrace:\n    " << exception.backtrace.join("\n    ")
  end
  result << "\n  context.stack_trace:\n    " << stack_trace_inspects.reverse.join("\n    ")
  ActiveRecord::Base.logger.send(level, result)
end

#mark_proceedingObject



62
63
64
# File 'lib/state_flow/context.rb', line 62

def mark_proceeding
  @mark_proceeding = true
end

#process(flow_or_named_event = flow) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/state_flow/context.rb', line 15

def process(flow_or_named_event = flow)
  transaction_with_recovering do
    flow_or_named_event.process(self)
    save_record_if_need
  end
  if options[:keep_process]
    last_current_key = current_attr_key
    while true
      @mark_proceeding = false
      transaction_with_recovering do
        flow.process(self)
        save_record_if_need if @mark_proceeding
      end
      break unless @mark_proceeding
      break if last_current_key == current_attr_key
      last_current_key = current_attr_key
    end
  end
  self
end

#record_reload_if_possibleObject



158
159
160
161
162
163
# File 'lib/state_flow/context.rb', line 158

def record_reload_if_possible
  return if record.new_record?
  manipulation = Manipulation.new(self, record, :reload)
  trace(manipulation)
  manipulation.execute 
end

#record_send(*args, &block) ⇒ Object



152
153
154
155
156
# File 'lib/state_flow/context.rb', line 152

def record_send(*args, &block)
  manipulation = Manipulation.new(self, record, *args, &block)
  trace(manipulation)
  manipulation.execute
end

#recovered?(exception) ⇒ Boolean

Returns:

  • (Boolean)


179
180
181
# File 'lib/state_flow/context.rb', line 179

def recovered?(exception)
  recovered_exceptions.include?(exception)
end

#recovered_exceptionsObject



175
176
177
# File 'lib/state_flow/context.rb', line 175

def recovered_exceptions
  @recovered_exceptions ||= []
end

#save_record_if_needObject



145
146
147
148
149
150
# File 'lib/state_flow/context.rb', line 145

def save_record_if_need
  return unless options[:save]
  manipulation = Manipulation.new(self, record, options[:save])
  trace(manipulation)
  manipulation.execute
end

#stack_traceObject



71
72
73
# File 'lib/state_flow/context.rb', line 71

def stack_trace
  @stack_trace ||= []
end

#stack_trace_inspectsObject



75
76
77
# File 'lib/state_flow/context.rb', line 75

def stack_trace_inspects
  stack_trace.map{|st| st.inspect}
end

#start_force_recoveringObject



79
# File 'lib/state_flow/context.rb', line 79

def start_force_recovering ; @force_recovering = true ; end

#trace(object) ⇒ Object



66
67
68
69
# File 'lib/state_flow/context.rb', line 66

def trace(object)
  ActiveRecord::Base.logger.debug(object.inspect)
  stack_trace << object
end

#transaction_rollbackObject



165
166
167
168
169
# File 'lib/state_flow/context.rb', line 165

def transaction_rollback
  manipulation = Manipulation.new(self, record.class.connection, :rollback_db_transaction)
  trace(manipulation)
  manipulation.execute
end

#with_force_recovering(target = nil, *recovering_method_and_args) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/state_flow/context.rb', line 83

def with_force_recovering(target = nil, *recovering_method_and_args)
  return yield unless force_recovering?
  begin
    return yield
  rescue Exception => exception
    log_with_stack_trace(:warn, "IGNORE EXCEPTION IN RECOVERING", 
        :exception => exception, :backtrace => true)
    if recovering_method_and_args.empty?
      return
    else
      return target.send(*recovering_method_and_args)
    end
  end
end