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
- #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
- #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 |
# File 'lib/solid_objects/activation.rb', line 14 def initialize(lease:) @lease = lease instance = Instance.find(lease.instance_id) @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.
114 115 116 |
# File 'lib/solid_objects/activation.rb', line 114 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
117 118 119 120 121 122 123 |
# File 'lib/solid_objects/activation.rb', line 117 def build_actor(instance) state_data = actor_class.definition.migrate_state(instance.state_version, instance.state) actor_class.new( actor_id: instance.actor_id, state: State.new(actor_class.definition.state_definition, state_data) ) end |
#claim_next_message ⇒ Message?
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 |
# File 'lib/solid_objects/activation.rb', line 126 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_generation: lease.generation, claimed_at: now ) end end |
#deactivate ⇒ void
This method returns an undefined value.
105 106 107 108 109 110 |
# File 'lib/solid_objects/activation.rb', line 105 def deactivate actor.deactivate lease.release rescue LostActivation nil end |
#drain ⇒ Integer
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/solid_objects/activation.rb', line 33 def drain processed_count = 0 started_at = monotonic_now @pass_exhausted = false loop do 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 end processed_count end |
#idle? ⇒ Boolean
73 74 75 |
# File 'lib/solid_objects/activation.rb', line 73 def idle? monotonic_now - @last_used_at >= SolidObjects.configuration.idle_deactivation_timeout end |
#lease_renewal_due? ⇒ Boolean
83 84 85 86 |
# File 'lib/solid_objects/activation.rb', line 83 def lease_renewal_due? lease.expires_at - SolidObjects.database_adapter.database_now <= SolidObjects.configuration.lease_renewal_interval end |
#monotonic_now ⇒ Float
179 180 181 |
# File 'lib/solid_objects/activation.rb', line 179 def monotonic_now ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) end |
#pass_exhausted? ⇒ Boolean
68 69 70 |
# File 'lib/solid_objects/activation.rb', line 68 def pass_exhausted? @pass_exhausted end |
#ready? ⇒ Boolean
57 58 59 60 61 62 63 64 65 |
# File 'lib/solid_objects/activation.rb', line 57 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_generation: lease.generation ).exists? end |
#recover_stale_claim(instance) ⇒ void
This method returns an undefined value.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/solid_objects/activation.rb', line 156 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_generation == lease.generation = . .destroy! return if .completed? || .dead? ReadyMessage.create!( message:, instance:, sequence: .sequence, available_at: SolidObjects.database_adapter.database_now ) end |
#renew_lease ⇒ void
This method returns an undefined value.
78 79 80 |
# File 'lib/solid_objects/activation.rb', line 78 def renew_lease @lease = lease.renew end |
#restore_state(state_data) ⇒ void
This method returns an undefined value.
97 98 99 100 101 102 |
# File 'lib/solid_objects/activation.rb', line 97 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.
89 90 91 92 93 94 |
# File 'lib/solid_objects/activation.rb', line 89 def now = SolidObjects.database_adapter.database_now ReadyMessage .where(instance_id: lease.instance_id, available_at: ..now) .update_all(available_at: now) end |