Class: SolidObjects::Activation
- Inherits:
-
Object
- Object
- SolidObjects::Activation
- Defined in:
- lib/solid_objects/activation.rb,
sig/generated/lib/solid_objects/activation.rbs
Instance Attribute Summary collapse
- #actor ⇒ Object readonly
-
#actor_class ⇒ Object
readonly
Returns the value of attribute actor_class.
- #lease ⇒ Object readonly
Instance Method Summary collapse
- #build_actor(instance) ⇒ Actor
- #claim_next_message ⇒ Message?
- #deactivate ⇒ void
- #drain ⇒ Integer
- #drain_messages(message_id: nil, deadline: nil) ⇒ Integer
- #drain_until(message_id:, deadline:) ⇒ Integer
- #idle? ⇒ Boolean
-
#initialize(lease:) ⇒ Activation
constructor
A new instance of Activation.
- #lease_renewal_due? ⇒ Boolean
- #monotonic_now ⇒ Float
- #pass_exhausted? ⇒ Boolean
- #ready? ⇒ Boolean
- #recover_stale_claim(instance) ⇒ void
- #release_lease ⇒ void
- #renew_lease ⇒ void
- #restore_state(state_data) ⇒ void
- #yield_ready_messages ⇒ void
Constructor Details
#initialize(lease:) ⇒ Activation
Returns a new instance of Activation.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/solid_objects/activation.rb', line 14 def initialize(lease:) @lease = lease instance = SolidObjects.database_adapter.with_lock_retry do Instance.find(lease.instance_id) end @actor_class = SolidObjects.registry.fetch(instance.actor_type) @actor = build_actor(instance) @last_used_at = monotonic_now @pass_exhausted = false actor.activate SolidObjects.instrument( :"activation.started", instance_id: instance.id, actor_type: instance.actor_type, actor_id: instance.actor_id, owner_id: lease.owner_id, generation: lease.generation ) end |
Instance Attribute Details
#actor ⇒ Object (readonly)
11 12 13 |
# File 'lib/solid_objects/activation.rb', line 11 def actor @actor end |
#actor_class ⇒ Object (readonly)
Returns the value of attribute actor_class.
121 122 123 |
# File 'lib/solid_objects/activation.rb', line 121 def actor_class @actor_class end |
#lease ⇒ Object (readonly)
11 12 13 |
# File 'lib/solid_objects/activation.rb', line 11 def lease @lease end |
Instance Method Details
#build_actor(instance) ⇒ Actor
151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/solid_objects/activation.rb', line 151 def build_actor(instance) state_data = ApplicationWriteGuard.call( actor_type: instance.actor_type, actor_id: instance.actor_id, operation: "state_migration" ) do actor_class.definition.migrate_state(instance.state_version, instance.state) end actor_class.new( actor_id: instance.actor_id, state: State.new(actor_class.definition.state_definition, state_data) ) end |
#claim_next_message ⇒ Message?
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/solid_objects/activation.rb', line 173 def lease.fenced_transaction do |instance| recover_stale_claim(instance) = ReadyMessage .where(instance_id: instance.id) .order(:sequence) .first next unless now = SolidObjects.database_adapter.database_now next if .available_at > now = Message.lock.find(.) .destroy! .update!( attempt_count: .attempt_count + 1, started_at: now ) ClaimedMessage.create!( message:, instance:, process_id: lease.owner_id, activation_token: lease.activation_token, activation_generation: lease.generation, claimed_at: now ) end end |
#deactivate ⇒ void
This method returns an undefined value.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/solid_objects/activation.rb', line 96 def deactivate actor.deactivate rescue => error SolidObjects.instrument( :"activation.deactivation_failed", instance_id: lease.instance_id, actor_type: actor.class.actor_type, actor_id: actor.actor_id, owner_id: lease.owner_id, generation: lease.generation, error_class: error.class.name, error_message: error. ) SolidObjects.configuration.logger.error( "SolidObjects activation deactivation failed " \ "actor_type=#{actor.class.actor_type.inspect} " \ "actor_id=#{actor.actor_id.inspect} " \ "error_class=#{error.class.name}" ) ensure release_lease end |
#drain ⇒ Integer
35 36 37 |
# File 'lib/solid_objects/activation.rb', line 35 def drain end |
#drain_messages(message_id: nil, deadline: nil) ⇒ Integer
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 |
# File 'lib/solid_objects/activation.rb', line 124 def (message_id: nil, deadline: nil) processed_count = 0 started_at = monotonic_now @pass_exhausted = false loop do break if deadline && monotonic_now >= deadline if processed_count >= SolidObjects.configuration. || monotonic_now - started_at >= SolidObjects.configuration.max_activation_duration @pass_exhausted = true break end = break unless Executor.new(activation: self, message:).call processed_count += 1 @last_used_at = monotonic_now break if .id == end processed_count end |
#drain_until(message_id:, deadline:) ⇒ Integer
40 41 42 |
# File 'lib/solid_objects/activation.rb', line 40 def drain_until(message_id:, deadline:) (message_id:, deadline:) end |
#idle? ⇒ Boolean
62 63 64 |
# File 'lib/solid_objects/activation.rb', line 62 def idle? monotonic_now - @last_used_at >= SolidObjects.configuration.idle_deactivation_timeout end |
#lease_renewal_due? ⇒ Boolean
72 73 74 75 |
# File 'lib/solid_objects/activation.rb', line 72 def lease_renewal_due? lease.expires_at - SolidObjects.database_adapter.database_now <= SolidObjects.configuration.lease_renewal_interval end |
#monotonic_now ⇒ Float
228 229 230 |
# File 'lib/solid_objects/activation.rb', line 228 def monotonic_now ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) end |
#pass_exhausted? ⇒ Boolean
57 58 59 |
# File 'lib/solid_objects/activation.rb', line 57 def pass_exhausted? @pass_exhausted end |
#ready? ⇒ Boolean
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/solid_objects/activation.rb', line 45 def ready? now = SolidObjects.database_adapter.database_now ReadyMessage.where(instance_id: lease.instance_id, available_at: ..now).exists? || ClaimedMessage.where( instance_id: lease.instance_id, process_id: lease.owner_id, activation_token: lease.activation_token, activation_generation: lease.generation ).exists? end |
#recover_stale_claim(instance) ⇒ void
This method returns an undefined value.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/solid_objects/activation.rb', line 204 def recover_stale_claim(instance) = ClaimedMessage .joins(:message) .where(instance_id: instance.id) .order("#{Message.table_name}.sequence") .first return unless return if .process_id == lease.owner_id && .activation_token == lease.activation_token && .activation_generation == lease.generation = . .destroy! return if .completed? || .dead? ReadyMessage.create!( message:, instance:, sequence: .sequence, available_at: SolidObjects.database_adapter.database_now ) end |
#release_lease ⇒ void
This method returns an undefined value.
166 167 168 169 170 |
# File 'lib/solid_objects/activation.rb', line 166 def release_lease lease.release rescue LostActivation nil end |
#renew_lease ⇒ void
This method returns an undefined value.
67 68 69 |
# File 'lib/solid_objects/activation.rb', line 67 def renew_lease @lease = lease.renew end |
#restore_state(state_data) ⇒ void
This method returns an undefined value.
88 89 90 91 92 93 |
# File 'lib/solid_objects/activation.rb', line 88 def restore_state(state_data) @actor = actor_class.new( actor_id: actor.actor_id, state: State.new(actor_class.definition.state_definition, state_data) ) end |
#yield_ready_messages ⇒ void
This method returns an undefined value.
78 79 80 81 82 83 84 85 |
# File 'lib/solid_objects/activation.rb', line 78 def SolidObjects.database_adapter.transaction do now = SolidObjects.database_adapter.database_now ReadyMessage .where(instance_id: lease.instance_id, available_at: ..now) .update_all(available_at: now) end end |