Class: SolidObjects::ActivationManager

Inherits:
Object
  • Object
show all
Defined in:
lib/solid_objects/activation_manager.rb,
sig/generated/lib/solid_objects/activation_manager.rbs

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(owner_id:, database_adapter: SolidObjects.database_adapter) ⇒ ActivationManager

Returns a new instance of ActivationManager.

RBS:

  • (owner_id: String, ?database_adapter: DatabaseAdapter) -> void

Parameters:

  • owner_id: (String)
  • database_adapter: (DatabaseAdapter) (defaults to: SolidObjects.database_adapter)


9
10
11
12
# File 'lib/solid_objects/activation_manager.rb', line 9

def initialize(owner_id:, database_adapter: SolidObjects.database_adapter)
  @owner_id = owner_id
  @database_adapter = database_adapter
end

Instance Attribute Details

#database_adapterObject (readonly)

Returns the value of attribute database_adapter.

Returns:

  • (Object)


26
27
28
# File 'lib/solid_objects/activation_manager.rb', line 26

def database_adapter
  @database_adapter
end

#owner_idObject (readonly)

Returns the value of attribute owner_id.

Returns:

  • (Object)


26
27
28
# File 'lib/solid_objects/activation_manager.rb', line 26

def owner_id
  @owner_id
end

Instance Method Details

#available_lease_sqlString

RBS:

  • () -> String

Returns:

  • (String)


111
112
113
114
115
116
# File 'lib/solid_objects/activation_manager.rb', line 111

def available_lease_sql
  table_name = Instance.table_name
  "#{table_name}.activation_owner_id IS NULL OR " \
    "#{table_name}.activation_expires_at IS NULL OR " \
    "#{table_name}.activation_expires_at <= ?"
end

#candidate_instance_ids(now) ⇒ Array[Integer]

RBS:

  • (Time) -> Array[Integer]

Parameters:

  • (Time)

Returns:

  • (Array[Integer])


66
67
68
# File 'lib/solid_objects/activation_manager.rb', line 66

def candidate_instance_ids(now)
  (ready_instance_ids(now) + claimed_instance_ids(now)).uniq
end

#claim(instance_id:) ⇒ Activation?

RBS:

  • (instance_id: Integer) -> Activation?

Parameters:

  • instance_id: (Integer)

Returns:



20
21
22
# File 'lib/solid_objects/activation_manager.rb', line 20

def claim(instance_id:)
  claim_from([ instance_id ])
end

#claim_from(instance_ids) ⇒ Activation?

RBS:

  • (Array[Integer]) -> Activation?

Parameters:

  • (Array[Integer])

Returns:



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/solid_objects/activation_manager.rb', line 29

def claim_from(instance_ids)
  lease = database_adapter.transaction do
    now = database_adapter.database_now
    claimed_lease = nil
    instance_ids.each do |instance_id|
      instance = database_adapter.lock_candidates(
        Instance.where(id: instance_id)
      ).first
      next unless instance
      next unless claimable?(instance, now)

      claimed_lease = Lease.claim(
        instance:,
        owner_id:,
        activation_token: SecureRandom.uuid,
        now:,
        database_adapter:
      )
      break if claimed_lease
    end
    claimed_lease
  end
  return unless lease

  SolidObjects.instrument(
    :"activation.claimed",
    instance_id: lease.instance_id,
    owner_id:,
    generation: lease.generation
  )
  Activation.new(lease:)
rescue
  lease&.release
  raise
end

#claim_nextActivation?

RBS:

  • () -> Activation?

Returns:



15
16
17
# File 'lib/solid_objects/activation_manager.rb', line 15

def claim_next
  claim_from(candidate_instance_ids(database_adapter.database_now))
end

#claimable?(instance, now) ⇒ Boolean

RBS:

  • (Instance, Time) -> bool

Parameters:

Returns:

  • (Boolean)


102
103
104
105
106
107
108
# File 'lib/solid_objects/activation_manager.rb', line 102

def claimable?(instance, now)
  return false if instance.paused_at
  return true unless instance.activation_owner_id
  return true unless instance.activation_expires_at

  instance.activation_expires_at <= now
end

#claimed_instance_ids(now) ⇒ Array[Integer]

RBS:

  • (Time) -> Array[Integer]

Parameters:

  • (Time)

Returns:

  • (Array[Integer])


87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/solid_objects/activation_manager.rb', line 87

def claimed_instance_ids(now)
  ClaimedMessage
    .joins(:instance)
    .where("#{Instance.table_name}.paused_at IS NULL")
    .where(available_lease_sql, now)
    .group(:instance_id)
    .order(
      Arel.sql("MIN(claimed_at)"),
      Arel.sql("MIN(#{ClaimedMessage.table_name}.id)")
    )
    .limit(SolidObjects.configuration.claim_scan_limit)
    .pluck(:instance_id)
end

#ready_instance_ids(now) ⇒ Array[Integer]

RBS:

  • (Time) -> Array[Integer]

Parameters:

  • (Time)

Returns:

  • (Array[Integer])


71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/solid_objects/activation_manager.rb', line 71

def ready_instance_ids(now)
  ReadyMessage
    .joins(:instance)
    .where(available_at: ..now)
    .where("#{Instance.table_name}.paused_at IS NULL")
    .where(available_lease_sql, now)
    .group(:instance_id)
    .order(
      Arel.sql("MIN(available_at)"),
      Arel.sql("MIN(#{ReadyMessage.table_name}.id)")
    )
    .limit(SolidObjects.configuration.claim_scan_limit)
    .pluck(:instance_id)
end