Class: SolidObjects::InstancePruner

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(now: SolidObjects.database_adapter.database_now, batch_size: SolidObjects.configuration.prune_batch_size) ⇒ InstancePruner

Returns a new instance of InstancePruner.

RBS:

  • (?now: Time, ?batch_size: Integer) -> void

Parameters:

  • now: (Time) (defaults to: SolidObjects.database_adapter.database_now)
  • batch_size: (Integer) (defaults to: SolidObjects.configuration.prune_batch_size)


9
10
11
12
13
14
15
# File 'lib/solid_objects/instance_pruner.rb', line 9

def initialize(
  now: SolidObjects.database_adapter.database_now,
  batch_size: SolidObjects.configuration.prune_batch_size
)
  @now = now
  @batch_size = batch_size
end

Instance Attribute Details

#batch_sizeObject (readonly)

Returns the value of attribute batch_size.

Returns:

  • (Object)


31
32
33
# File 'lib/solid_objects/instance_pruner.rb', line 31

def batch_size
  @batch_size
end

#nowObject (readonly)

Returns the value of attribute now.

Returns:

  • (Object)


31
32
33
# File 'lib/solid_objects/instance_pruner.rb', line 31

def now
  @now
end

Instance Method Details

#policy_relationsArray[ActiveRecord::Relation[Instance]]

RBS:

  • () -> Array[ActiveRecord::Relation[Instance]]

Returns:



34
35
36
37
38
39
40
# File 'lib/solid_objects/instance_pruner.rb', line 34

def policy_relations
  SolidObjects.configuration.instance_retention_by_actor_type.map do |actor_type, retention|
    prunable
      .where(actor_type: actor_type.to_s)
      .where("COALESCE(last_used_at, created_at) < ?", now - retention)
  end
end

#previewInteger

RBS:

  • () -> Integer

Returns:

  • (Integer)


18
19
20
# File 'lib/solid_objects/instance_pruner.rb', line 18

def preview
  policy_relations.sum(&:count)
end

#prunableActiveRecord::Relation[Instance]

RBS:

  • () -> ActiveRecord::Relation[Instance]

Returns:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/solid_objects/instance_pruner.rb', line 43

def prunable
  Instance
    .where(activation_owner_id: nil, paused_at: nil)
    .where.not(id: ReadyMessage.select(:instance_id))
    .where.not(id: ClaimedMessage.select(:instance_id))
    .where.not(
      id: Reminder.where(status: "scheduled").select(:instance_id)
    )
    .where.not(
      id: Effect.where.not(status: "completed").select(:instance_id)
    )
    .where.not(
      id: Broadcast.where.not(status: "delivered").select(:instance_id)
    )
    .where.not(id: DeadLetter.select(:instance_id))
end

#pruneInteger

RBS:

  • () -> Integer

Returns:

  • (Integer)


23
24
25
26
27
# File 'lib/solid_objects/instance_pruner.rb', line 23

def prune
  policy_relations.sum { |relation| prune_relation(relation) }.tap do |count|
    SolidObjects.instrument(:"instances.pruned", count:)
  end
end

#prune_instance(instance_id, relation) ⇒ Integer

RBS:

  • (Integer, ActiveRecord::Relation[Instance]) -> Integer

Parameters:

Returns:

  • (Integer)


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/solid_objects/instance_pruner.rb', line 77

def prune_instance(instance_id, relation)
  expired_actor = SolidObjects.database_adapter.transaction do
    instance = Instance.lock.find_by(id: instance_id)
    next unless instance
    next unless relation.where(id: instance_id).exists?

    identity = {
      instance_id:,
      actor_type: instance.actor_type,
      actor_id: instance.actor_id
    }
    instance.delete
    identity
  end
  return 0 unless expired_actor

  SolidObjects.instrument(:"actor.expired", **expired_actor)
  1
end

#prune_relation(relation) ⇒ Integer

RBS:

  • (ActiveRecord::Relation[Instance]) -> Integer

Parameters:

Returns:

  • (Integer)


61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/solid_objects/instance_pruner.rb', line 61

def prune_relation(relation)
  deleted = 0

  loop do
    instance_ids = relation.limit(batch_size).pluck(:id)
    break if instance_ids.empty?

    instance_ids.each do |instance_id|
      deleted += prune_instance(instance_id, relation)
    end
  end

  deleted
end