solid_objects 0.16.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b060638b79ca2236a6530f8c478fe28ac0453fc514a0daeeb5f0f3a400f446ee
|
|
4
|
+
data.tar.gz: 31424c65ecc34caab85a2296b3e2f7055f731b07a5db16022fc48d1fcc860ed6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6fee1b678cfb18e2a0b59c1e275a079631570b7a7b44cdd9edc2e0d880ec7efc688f9ee59bc9e3afb2742f355f793939f9a263f07f9e3a7bc466c07367dcbb23
|
|
7
|
+
data.tar.gz: 5d92fe6f884c53b757c5dde1ab372afe0200a3f509ddef737f75bd8810f42e224def36ce363abf57d1e41326fe2dc5ff0985b111deed3656db960a3889b26d9c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.1 - 2026-10-02
|
|
4
|
+
|
|
5
|
+
- Fix the SQLite join order of the claimed-message scan. The query in
|
|
6
|
+
`ActivationManager#claimed_instance_ids` has no condition on a
|
|
7
|
+
claimed-message column. The claimed-messages table is a short queue, so it is
|
|
8
|
+
often empty when `ANALYZE` or `PRAGMA optimize` runs, and `sqlite_stat1` then
|
|
9
|
+
has no row for it. Without statistics, SQLite assumed that the table was
|
|
10
|
+
large, and it scanned every instance on each worker poll. The scan now uses
|
|
11
|
+
`CROSS JOIN`, which SQLite keeps as a fixed join order, so it starts from the
|
|
12
|
+
claimed messages. PostgreSQL and MySQL treat `CROSS JOIN` with an equality as
|
|
13
|
+
an inner join and keep their plans. The ids and their order do not change.
|
|
14
|
+
- Find SQLite effect recovery candidates through the processing effects.
|
|
15
|
+
`sqlite_stat1` records only the average row count for each effect status.
|
|
16
|
+
When most effects are complete, SQLite estimated that `status = 'processing'`
|
|
17
|
+
matched most of the effects table. It then read every recovery row in key
|
|
18
|
+
order to skip a sort, on each effect poll. An index on the recovery filter
|
|
19
|
+
does not help, because a recovery row keeps `retired_at` empty after a normal
|
|
20
|
+
completion. On SQLite the status test now carries
|
|
21
|
+
`likelihood(..., 0.000001)`, so the plan starts from `idx_so_effects_poll`.
|
|
22
|
+
The PostgreSQL and MySQL queries do not change.
|
|
23
|
+
|
|
3
24
|
## 0.16.0 - 2026-09-23
|
|
4
25
|
|
|
5
26
|
- Find a message whose reference a caller lost.
|
|
@@ -86,7 +86,8 @@ module SolidObjects
|
|
|
86
86
|
# @rbs (Time) -> Array[Integer]
|
|
87
87
|
def claimed_instance_ids(now)
|
|
88
88
|
ClaimedMessage
|
|
89
|
-
.joins(
|
|
89
|
+
.joins("CROSS JOIN #{Instance.table_name}")
|
|
90
|
+
.where("#{Instance.table_name}.id = #{ClaimedMessage.table_name}.instance_id")
|
|
90
91
|
.where("#{Instance.table_name}.paused_at IS NULL")
|
|
91
92
|
.where(available_lease_sql, now)
|
|
92
93
|
.group(:instance_id)
|
|
@@ -63,17 +63,22 @@ module SolidObjects
|
|
|
63
63
|
effects = Effect.table_name
|
|
64
64
|
owners = Process.table_name
|
|
65
65
|
bindings = EffectRecovery.table_name
|
|
66
|
-
|
|
66
|
+
family = DatabaseAdapter.family(Record.connection)
|
|
67
|
+
heartbeat = case family
|
|
67
68
|
when :postgresql then "EXTRACT(EPOCH FROM #{owners}.last_heartbeat_at)"
|
|
68
69
|
when :mysql then "UNIX_TIMESTAMP(#{owners}.last_heartbeat_at)"
|
|
69
70
|
else "CAST(STRFTIME('%s', #{owners}.last_heartbeat_at) AS REAL)"
|
|
70
71
|
end
|
|
72
|
+
processing = case family
|
|
73
|
+
when :postgresql, :mysql then "#{effects}.status = ?"
|
|
74
|
+
else "likelihood(#{effects}.status = ?, 0.000001)"
|
|
75
|
+
end
|
|
71
76
|
now = SolidObjects.database_adapter.database_clock_now.to_f
|
|
72
77
|
threshold = SolidObjects.configuration.process_alive_threshold
|
|
73
78
|
EffectRecovery.joins("INNER JOIN #{effects} ON #{effects}.effect_id = #{bindings}.effect_id")
|
|
74
79
|
.joins("LEFT JOIN #{owners} ON #{owners}.id = #{effects}.claimed_by")
|
|
75
80
|
.where(retired_at: nil).where.not(recovery_operation: nil)
|
|
76
|
-
.where(
|
|
81
|
+
.where(processing, "processing")
|
|
77
82
|
.where("#{owners}.id IS NULL OR #{heartbeat} <= ? - CASE WHEN #{bindings}.recovery_timeout > ? THEN #{bindings}.recovery_timeout ELSE ? END", now, threshold, threshold)
|
|
78
83
|
.order(:effect_id).limit(SolidObjects.configuration.claim_scan_limit)
|
|
79
84
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solid_objects
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.16.
|
|
4
|
+
version: 0.16.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lucas Carlson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actioncable
|