familia 1.2.3 → 2.0.0.pre.pre
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 +4 -4
- data/.github/workflows/ci.yml +68 -0
- data/.github/workflows/docs.yml +64 -0
- data/.gitignore +3 -0
- data/.pre-commit-config.yaml +3 -1
- data/.rubocop.yml +16 -9
- data/.rubocop_todo.yml +177 -31
- data/.yardopts +9 -0
- data/CLAUDE.md +141 -0
- data/Gemfile +15 -2
- data/Gemfile.lock +61 -61
- data/README.md +39 -23
- data/bin/irb +3 -0
- data/docs/connection_pooling.md +317 -0
- data/familia.gemspec +8 -5
- data/lib/familia/base.rb +19 -9
- data/lib/familia/connection.rb +232 -65
- data/lib/familia/core_ext.rb +1 -1
- data/lib/familia/datatype/commands.rb +59 -0
- data/lib/familia/{redistype → datatype}/serialization.rb +9 -13
- data/lib/familia/{redistype → datatype}/types/hashkey.rb +25 -25
- data/lib/familia/{redistype → datatype}/types/list.rb +13 -13
- data/lib/familia/{redistype → datatype}/types/sorted_set.rb +20 -20
- data/lib/familia/{redistype → datatype}/types/string.rb +22 -21
- data/lib/familia/{redistype → datatype}/types/unsorted_set.rb +11 -11
- data/lib/familia/datatype.rb +243 -0
- data/lib/familia/errors.rb +5 -2
- data/lib/familia/features/expiration.rb +33 -34
- data/lib/familia/features/quantization.rb +9 -3
- data/lib/familia/features/safe_dump.rb +2 -3
- data/lib/familia/features.rb +2 -2
- data/lib/familia/horreum/class_methods.rb +97 -130
- data/lib/familia/horreum/commands.rb +46 -51
- data/lib/familia/horreum/connection.rb +82 -0
- data/lib/familia/horreum/{relations_management.rb → related_fields_management.rb} +37 -35
- data/lib/familia/horreum/serialization.rb +61 -198
- data/lib/familia/horreum/settings.rb +6 -17
- data/lib/familia/horreum/utils.rb +11 -10
- data/lib/familia/horreum.rb +69 -60
- data/lib/familia/logging.rb +12 -12
- data/lib/familia/multi_result.rb +72 -0
- data/lib/familia/refinements.rb +7 -44
- data/lib/familia/settings.rb +11 -11
- data/lib/familia/utils.rb +123 -90
- data/lib/familia/version.rb +4 -21
- data/lib/familia.rb +17 -12
- data/lib/middleware/database_middleware.rb +150 -0
- data/try/configuration/scenarios_try.rb +65 -0
- data/try/core/connection_try.rb +58 -0
- data/try/core/errors_try.rb +93 -0
- data/try/core/extensions_try.rb +26 -0
- data/try/{10_familia_try.rb → core/familia_extended_try.rb} +11 -10
- data/try/{00_familia_try.rb → core/familia_try.rb} +5 -3
- data/try/core/middleware_try.rb +68 -0
- data/try/core/refinements_try.rb +39 -0
- data/try/core/settings_try.rb +76 -0
- data/try/core/tools_try.rb +54 -0
- data/try/core/utils_try.rb +189 -0
- data/try/{26_redis_bool_try.rb → datatypes/boolean_try.rb} +4 -2
- data/try/datatypes/datatype_base_try.rb +69 -0
- data/try/{25_redis_type_hash_try.rb → datatypes/hash_try.rb} +5 -3
- data/try/{23_redis_type_list_try.rb → datatypes/list_try.rb} +5 -3
- data/try/{22_redis_type_set_try.rb → datatypes/set_try.rb} +5 -3
- data/try/{21_redis_type_zset_try.rb → datatypes/sorted_set_try.rb} +6 -4
- data/try/{24_redis_type_string_try.rb → datatypes/string_try.rb} +8 -8
- data/try/edge_cases/empty_identifiers_try.rb +48 -0
- data/try/{92_symbolize_try.rb → edge_cases/hash_symbolization_try.rb} +12 -8
- data/try/edge_cases/json_serialization_try.rb +85 -0
- data/try/edge_cases/race_conditions_try.rb +60 -0
- data/try/edge_cases/reserved_keywords_try.rb +59 -0
- data/try/{93_string_coercion_try.rb → edge_cases/string_coercion_try.rb} +63 -60
- data/try/edge_cases/ttl_side_effects_try.rb +51 -0
- data/try/features/expiration_try.rb +86 -0
- data/try/features/quantization_try.rb +90 -0
- data/try/{35_feature_safedump_try.rb → features/safe_dump_advanced_try.rb} +7 -6
- data/try/features/safe_dump_try.rb +137 -0
- data/try/{test_helpers.rb → helpers/test_helpers.rb} +25 -60
- data/try/{27_redis_horreum_try.rb → horreum/base_try.rb} +39 -14
- data/try/horreum/class_methods_try.rb +41 -0
- data/try/horreum/commands_try.rb +49 -0
- data/try/{29_redis_horreum_initialization_try.rb → horreum/initialization_try.rb} +9 -7
- data/try/horreum/relations_try.rb +146 -0
- data/try/{28_redis_horreum_serialization_try.rb → horreum/serialization_try.rb} +13 -11
- data/try/horreum/settings_try.rb +43 -0
- data/try/integration/cross_component_try.rb +46 -0
- data/try/{41_customer_safedump_try.rb → models/customer_safe_dump_try.rb} +9 -7
- data/try/{40_customer_try.rb → models/customer_try.rb} +20 -17
- data/try/models/datatype_base_try.rb +101 -0
- data/try/{30_familia_object_try.rb → models/familia_object_try.rb} +18 -16
- data/try/performance/benchmarks_try.rb +55 -0
- data/try/pooling/README.md +20 -0
- data/try/pooling/configurable_stress_test_try.rb +435 -0
- data/try/pooling/connection_pool_test_try.rb +273 -0
- data/try/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +192 -0
- data/try/pooling/lib/connection_pool_metrics.rb +372 -0
- data/try/pooling/lib/connection_pool_stress_test.rb +959 -0
- data/try/pooling/lib/connection_pool_threading_models.rb +421 -0
- data/try/pooling/lib/visualize_stress_results.rb +434 -0
- data/try/pooling/pool_siege_try.rb +509 -0
- data/try/pooling/run_stress_tests_try.rb +482 -0
- data/try/prototypes/atomic_saves_v1_context_proxy.rb +121 -0
- data/try/prototypes/atomic_saves_v2_connection_switching.rb +161 -0
- data/try/prototypes/atomic_saves_v3_connection_pool.rb +189 -0
- data/try/prototypes/atomic_saves_v4.rb +105 -0
- data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +124 -0
- data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +192 -0
- metadata +124 -38
- data/.github/workflows/ruby.yml +0 -71
- data/VERSION.yml +0 -4
- data/lib/familia/redistype/commands.rb +0 -59
- data/lib/familia/redistype.rb +0 -228
- data/lib/familia/tools.rb +0 -68
- data/lib/redis_middleware.rb +0 -109
- data/try/20_redis_type_try.rb +0 -70
- data/try/91_json_bug_try.rb +0 -86
@@ -0,0 +1,192 @@
|
|
1
|
+
# try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb
|
2
|
+
|
3
|
+
##
|
4
|
+
# Atomic Save V3 Proof of Concept - Connection Pool Integration
|
5
|
+
#
|
6
|
+
# This implementation explores atomic saves with Database connection pooling
|
7
|
+
# for thread safety in multi-threaded environments (like Puma).
|
8
|
+
#
|
9
|
+
# Key Goals:
|
10
|
+
# 1. **Connection Pool Integration**: Use ConnectionPool gem for thread safety
|
11
|
+
# 2. **Dual Approach Testing**: Compare proxy vs explicit connection passing
|
12
|
+
# 3. **Thread Safety Validation**: Prove pool handles concurrent operations
|
13
|
+
# 4. **Separate Transaction Boundaries**: Each atomic block gets own transaction
|
14
|
+
#
|
15
|
+
# Approaches Tested:
|
16
|
+
# - Proxy Approach: Familia.atomic { ... } (transparent, V2 style)
|
17
|
+
# - Explicit Approach: Familia.atomic { |conn| ... } (clear boundaries)
|
18
|
+
|
19
|
+
require 'connection_pool'
|
20
|
+
require 'json'
|
21
|
+
|
22
|
+
# Test models
|
23
|
+
class BankAccount < Familia::Horreum
|
24
|
+
identifier_field :account_number
|
25
|
+
field :account_number
|
26
|
+
field :balance
|
27
|
+
field :holder_name
|
28
|
+
field :metadata # Variable-sized JSON field for workload simulation
|
29
|
+
|
30
|
+
def init
|
31
|
+
@account_number ||= SecureRandom.hex(8)
|
32
|
+
@balance = @balance.to_f if @balance
|
33
|
+
@metadata = @metadata.is_a?(String) ? JSON.parse(@metadata) : @metadata rescue @metadata
|
34
|
+
end
|
35
|
+
|
36
|
+
def balance
|
37
|
+
@balance&.to_f
|
38
|
+
end
|
39
|
+
|
40
|
+
def withdraw(amount)
|
41
|
+
raise "Insufficient funds" if balance < amount
|
42
|
+
self.balance -= amount
|
43
|
+
end
|
44
|
+
|
45
|
+
def deposit(amount)
|
46
|
+
self.balance += amount
|
47
|
+
end
|
48
|
+
|
49
|
+
def metadata=(value)
|
50
|
+
@metadata = value.is_a?(Hash) || value.is_a?(Array) ? JSON.generate(value) : value
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add method that accepts explicit connection
|
54
|
+
def save(using: nil)
|
55
|
+
if using
|
56
|
+
# Use provided connection explicitly
|
57
|
+
original_instance = @dbclient
|
58
|
+
@dbclient = using
|
59
|
+
begin
|
60
|
+
super()
|
61
|
+
ensure
|
62
|
+
@dbclient = original_instance
|
63
|
+
end
|
64
|
+
else
|
65
|
+
# Use normal save behavior
|
66
|
+
super()
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class TransactionRecord < Familia::Horreum
|
72
|
+
identifier_field :transaction_id
|
73
|
+
field :transaction_id
|
74
|
+
field :from_account
|
75
|
+
field :to_account
|
76
|
+
field :amount
|
77
|
+
field :status
|
78
|
+
field :created_at
|
79
|
+
|
80
|
+
def initialize(from: nil, to: nil, amount: 0)
|
81
|
+
@transaction_id = SecureRandom.hex(8)
|
82
|
+
@from_account = from
|
83
|
+
@to_account = to
|
84
|
+
@amount = amount.to_f
|
85
|
+
@status = "pending"
|
86
|
+
@created_at = Time.now.to_i
|
87
|
+
end
|
88
|
+
|
89
|
+
def amount
|
90
|
+
@amount&.to_f
|
91
|
+
end
|
92
|
+
|
93
|
+
def created_at
|
94
|
+
@created_at&.to_i
|
95
|
+
end
|
96
|
+
|
97
|
+
def save(using: nil)
|
98
|
+
if using
|
99
|
+
original_instance = @dbclient
|
100
|
+
@dbclient = using
|
101
|
+
begin
|
102
|
+
super()
|
103
|
+
ensure
|
104
|
+
@dbclient = original_instance
|
105
|
+
end
|
106
|
+
else
|
107
|
+
super()
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
module Familia
|
113
|
+
# Connection pool for Database connections
|
114
|
+
@@connection_pool = ConnectionPool.new(size: 10, timeout: 5) do
|
115
|
+
Redis.new(url: Familia.uri.to_s)
|
116
|
+
end
|
117
|
+
|
118
|
+
class << self
|
119
|
+
def connection_pool
|
120
|
+
@@connection_pool
|
121
|
+
end
|
122
|
+
|
123
|
+
def current_transaction
|
124
|
+
Thread.current[:familia_current_transaction_v3]
|
125
|
+
end
|
126
|
+
|
127
|
+
def current_transaction=(transaction)
|
128
|
+
Thread.current[:familia_current_transaction_v3] = transaction
|
129
|
+
end
|
130
|
+
|
131
|
+
# Proxy approach - transparent like V2
|
132
|
+
def atomic(&block)
|
133
|
+
if current_transaction
|
134
|
+
# Nested atomic - create separate transaction
|
135
|
+
atomic_separate(&block)
|
136
|
+
else
|
137
|
+
# Use connection pool to get connection
|
138
|
+
# For this prototype, we'll use a simple approach that works with Redis
|
139
|
+
connection_pool.with do |conn|
|
140
|
+
begin
|
141
|
+
# Store the connection for use within the block
|
142
|
+
self.current_transaction = conn
|
143
|
+
result = yield
|
144
|
+
result
|
145
|
+
ensure
|
146
|
+
self.current_transaction = nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Explicit approach - connection passed to block
|
153
|
+
def atomic_explicit(&block)
|
154
|
+
connection_pool.with do |conn|
|
155
|
+
# For this prototype, pass the connection directly
|
156
|
+
yield(conn)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Helper for separate nested transactions
|
161
|
+
def atomic_separate(&block)
|
162
|
+
connection_pool.with do |conn|
|
163
|
+
begin
|
164
|
+
old_transaction = current_transaction
|
165
|
+
# Use a separate connection for nested transactions
|
166
|
+
self.current_transaction = conn
|
167
|
+
result = yield
|
168
|
+
result
|
169
|
+
ensure
|
170
|
+
self.current_transaction = old_transaction
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Override dbclient method for proxy approach
|
177
|
+
module ConnectionPoolRedis
|
178
|
+
def dbclient
|
179
|
+
Familia.current_transaction || super
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Inject into Horreum for proxy approach
|
184
|
+
class Horreum
|
185
|
+
prepend ConnectionPoolRedis
|
186
|
+
end
|
187
|
+
|
188
|
+
# Inject into DataType for proxy approach
|
189
|
+
class DataType
|
190
|
+
prepend ConnectionPoolRedis
|
191
|
+
end
|
192
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: familia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -9,6 +9,48 @@ bindir: exe
|
|
9
9
|
cert_chain: []
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: benchmark
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: connection_pool
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: csv
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
12
54
|
- !ruby/object:Gem::Dependency
|
13
55
|
name: logger
|
14
56
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,28 +113,40 @@ dependencies:
|
|
71
113
|
- - "~>"
|
72
114
|
- !ruby/object:Gem::Version
|
73
115
|
version: '1.3'
|
74
|
-
description: 'Familia: An ORM for
|
75
|
-
in Redis'
|
116
|
+
description: 'Familia: An ORM for Valkey-compatible databases in Ruby.. Organize and
|
117
|
+
store ruby objects in Valkey/Redis'
|
76
118
|
email: gems@solutious.com
|
77
119
|
executables: []
|
78
120
|
extensions: []
|
79
121
|
extra_rdoc_files: []
|
80
122
|
files:
|
81
|
-
- ".github/workflows/
|
123
|
+
- ".github/workflows/ci.yml"
|
124
|
+
- ".github/workflows/docs.yml"
|
82
125
|
- ".gitignore"
|
83
126
|
- ".pre-commit-config.yaml"
|
84
127
|
- ".rubocop.yml"
|
85
128
|
- ".rubocop_todo.yml"
|
129
|
+
- ".yardopts"
|
130
|
+
- CLAUDE.md
|
86
131
|
- Gemfile
|
87
132
|
- Gemfile.lock
|
88
133
|
- LICENSE.txt
|
89
134
|
- README.md
|
90
|
-
-
|
135
|
+
- bin/irb
|
136
|
+
- docs/connection_pooling.md
|
91
137
|
- familia.gemspec
|
92
138
|
- lib/familia.rb
|
93
139
|
- lib/familia/base.rb
|
94
140
|
- lib/familia/connection.rb
|
95
141
|
- lib/familia/core_ext.rb
|
142
|
+
- lib/familia/datatype.rb
|
143
|
+
- lib/familia/datatype/commands.rb
|
144
|
+
- lib/familia/datatype/serialization.rb
|
145
|
+
- lib/familia/datatype/types/hashkey.rb
|
146
|
+
- lib/familia/datatype/types/list.rb
|
147
|
+
- lib/familia/datatype/types/sorted_set.rb
|
148
|
+
- lib/familia/datatype/types/string.rb
|
149
|
+
- lib/familia/datatype/types/unsorted_set.rb
|
96
150
|
- lib/familia/errors.rb
|
97
151
|
- lib/familia/features.rb
|
98
152
|
- lib/familia/features/expiration.rb
|
@@ -101,45 +155,77 @@ files:
|
|
101
155
|
- lib/familia/horreum.rb
|
102
156
|
- lib/familia/horreum/class_methods.rb
|
103
157
|
- lib/familia/horreum/commands.rb
|
104
|
-
- lib/familia/horreum/
|
158
|
+
- lib/familia/horreum/connection.rb
|
159
|
+
- lib/familia/horreum/related_fields_management.rb
|
105
160
|
- lib/familia/horreum/serialization.rb
|
106
161
|
- lib/familia/horreum/settings.rb
|
107
162
|
- lib/familia/horreum/utils.rb
|
108
163
|
- lib/familia/logging.rb
|
109
|
-
- lib/familia/
|
110
|
-
- lib/familia/redistype/commands.rb
|
111
|
-
- lib/familia/redistype/serialization.rb
|
112
|
-
- lib/familia/redistype/types/hashkey.rb
|
113
|
-
- lib/familia/redistype/types/list.rb
|
114
|
-
- lib/familia/redistype/types/sorted_set.rb
|
115
|
-
- lib/familia/redistype/types/string.rb
|
116
|
-
- lib/familia/redistype/types/unsorted_set.rb
|
164
|
+
- lib/familia/multi_result.rb
|
117
165
|
- lib/familia/refinements.rb
|
118
166
|
- lib/familia/settings.rb
|
119
|
-
- lib/familia/tools.rb
|
120
167
|
- lib/familia/utils.rb
|
121
168
|
- lib/familia/version.rb
|
122
|
-
- lib/
|
123
|
-
- try/
|
124
|
-
- try/
|
125
|
-
- try/
|
126
|
-
- try/
|
127
|
-
- try/
|
128
|
-
- try/
|
129
|
-
- try/
|
130
|
-
- try/
|
131
|
-
- try/
|
132
|
-
- try/
|
133
|
-
- try/
|
134
|
-
- try/
|
135
|
-
- try/
|
136
|
-
- try/
|
137
|
-
- try/
|
138
|
-
- try/
|
139
|
-
- try/
|
140
|
-
- try/
|
141
|
-
- try/
|
142
|
-
- try/
|
169
|
+
- lib/middleware/database_middleware.rb
|
170
|
+
- try/configuration/scenarios_try.rb
|
171
|
+
- try/core/connection_try.rb
|
172
|
+
- try/core/errors_try.rb
|
173
|
+
- try/core/extensions_try.rb
|
174
|
+
- try/core/familia_extended_try.rb
|
175
|
+
- try/core/familia_try.rb
|
176
|
+
- try/core/middleware_try.rb
|
177
|
+
- try/core/refinements_try.rb
|
178
|
+
- try/core/settings_try.rb
|
179
|
+
- try/core/tools_try.rb
|
180
|
+
- try/core/utils_try.rb
|
181
|
+
- try/datatypes/boolean_try.rb
|
182
|
+
- try/datatypes/datatype_base_try.rb
|
183
|
+
- try/datatypes/hash_try.rb
|
184
|
+
- try/datatypes/list_try.rb
|
185
|
+
- try/datatypes/set_try.rb
|
186
|
+
- try/datatypes/sorted_set_try.rb
|
187
|
+
- try/datatypes/string_try.rb
|
188
|
+
- try/edge_cases/empty_identifiers_try.rb
|
189
|
+
- try/edge_cases/hash_symbolization_try.rb
|
190
|
+
- try/edge_cases/json_serialization_try.rb
|
191
|
+
- try/edge_cases/race_conditions_try.rb
|
192
|
+
- try/edge_cases/reserved_keywords_try.rb
|
193
|
+
- try/edge_cases/string_coercion_try.rb
|
194
|
+
- try/edge_cases/ttl_side_effects_try.rb
|
195
|
+
- try/features/expiration_try.rb
|
196
|
+
- try/features/quantization_try.rb
|
197
|
+
- try/features/safe_dump_advanced_try.rb
|
198
|
+
- try/features/safe_dump_try.rb
|
199
|
+
- try/helpers/test_helpers.rb
|
200
|
+
- try/horreum/base_try.rb
|
201
|
+
- try/horreum/class_methods_try.rb
|
202
|
+
- try/horreum/commands_try.rb
|
203
|
+
- try/horreum/initialization_try.rb
|
204
|
+
- try/horreum/relations_try.rb
|
205
|
+
- try/horreum/serialization_try.rb
|
206
|
+
- try/horreum/settings_try.rb
|
207
|
+
- try/integration/cross_component_try.rb
|
208
|
+
- try/models/customer_safe_dump_try.rb
|
209
|
+
- try/models/customer_try.rb
|
210
|
+
- try/models/datatype_base_try.rb
|
211
|
+
- try/models/familia_object_try.rb
|
212
|
+
- try/performance/benchmarks_try.rb
|
213
|
+
- try/pooling/README.md
|
214
|
+
- try/pooling/configurable_stress_test_try.rb
|
215
|
+
- try/pooling/connection_pool_test_try.rb
|
216
|
+
- try/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb
|
217
|
+
- try/pooling/lib/connection_pool_metrics.rb
|
218
|
+
- try/pooling/lib/connection_pool_stress_test.rb
|
219
|
+
- try/pooling/lib/connection_pool_threading_models.rb
|
220
|
+
- try/pooling/lib/visualize_stress_results.rb
|
221
|
+
- try/pooling/pool_siege_try.rb
|
222
|
+
- try/pooling/run_stress_tests_try.rb
|
223
|
+
- try/prototypes/atomic_saves_v1_context_proxy.rb
|
224
|
+
- try/prototypes/atomic_saves_v2_connection_switching.rb
|
225
|
+
- try/prototypes/atomic_saves_v3_connection_pool.rb
|
226
|
+
- try/prototypes/atomic_saves_v4.rb
|
227
|
+
- try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb
|
228
|
+
- try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb
|
143
229
|
homepage: https://github.com/delano/familia
|
144
230
|
licenses:
|
145
231
|
- MIT
|
@@ -152,7 +238,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
238
|
requirements:
|
153
239
|
- - ">="
|
154
240
|
- !ruby/object:Gem::Version
|
155
|
-
version:
|
241
|
+
version: '3.4'
|
156
242
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
243
|
requirements:
|
158
244
|
- - ">="
|
@@ -161,5 +247,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
247
|
requirements: []
|
162
248
|
rubygems_version: 3.6.9
|
163
249
|
specification_version: 4
|
164
|
-
summary: An ORM for
|
250
|
+
summary: An ORM for Valkey-compatible databases in Ruby.
|
165
251
|
test_files: []
|
data/.github/workflows/ruby.yml
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
name: Ruby
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- main
|
7
|
-
|
8
|
-
pull_request:
|
9
|
-
|
10
|
-
workflow_dispatch:
|
11
|
-
|
12
|
-
jobs:
|
13
|
-
build:
|
14
|
-
runs-on: ubuntu-latest
|
15
|
-
name: Ruby ${{ matrix.ruby }}
|
16
|
-
strategy:
|
17
|
-
matrix:
|
18
|
-
include:
|
19
|
-
- ruby: '3.3'
|
20
|
-
bundler: latest
|
21
|
-
rubygems: latest
|
22
|
-
|
23
|
-
- ruby: '3.2'
|
24
|
-
bundler: latest
|
25
|
-
rubygems: latest
|
26
|
-
|
27
|
-
- ruby: '3.1'
|
28
|
-
bundler: latest
|
29
|
-
rubygems: latest
|
30
|
-
|
31
|
-
- ruby: '3.0'
|
32
|
-
bundler: latest
|
33
|
-
rubygems: latest
|
34
|
-
|
35
|
-
- ruby: '2.7'
|
36
|
-
bundler: '2.4.22'
|
37
|
-
rubygems: '3.2.3'
|
38
|
-
|
39
|
-
services:
|
40
|
-
redis:
|
41
|
-
image: redis:bookworm@sha256:e422889e156ebea83856b6ff973bfe0c86bce867d80def228044eeecf925592b
|
42
|
-
# Set health checks to wait until redis has started
|
43
|
-
options: >-
|
44
|
-
--health-cmd "redis-cli ping"
|
45
|
-
--health-interval 10s
|
46
|
-
--health-timeout 3s
|
47
|
-
--health-retries 5
|
48
|
-
ports:
|
49
|
-
# https://docs.github.com/en/actions/using-containerized-services/creating-redis-service-containers#running-jobs-in-containers
|
50
|
-
# Maps port 6379 on service container to the host
|
51
|
-
- 6379:6379
|
52
|
-
|
53
|
-
steps:
|
54
|
-
- uses: actions/checkout@v4
|
55
|
-
- name: Set up Ruby
|
56
|
-
uses: ruby/setup-ruby@v1
|
57
|
-
with:
|
58
|
-
ruby-version: ${{ matrix.ruby }}
|
59
|
-
rubygems: ${{ matrix.rubygems }}
|
60
|
-
bundler: ${{ matrix.bundler }}
|
61
|
-
# When the following is true, also run "bundle install",
|
62
|
-
# and cache the result automatically. Ran into an issue
|
63
|
-
# with the caching and multiple ruby versions. Needs
|
64
|
-
# further investigation.
|
65
|
-
bundler-cache: false
|
66
|
-
|
67
|
-
- name: Re-run bundle install
|
68
|
-
run: bundle install
|
69
|
-
|
70
|
-
- name: Run the tryouts
|
71
|
-
run: bundle exec try -v try/*_try.rb
|
data/VERSION.yml
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
# rubocop:disable all
|
2
|
-
|
3
|
-
class Familia::RedisType
|
4
|
-
|
5
|
-
# Must be included in all RedisType classes to provide Redis
|
6
|
-
# commands. The class must have a rediskey method.
|
7
|
-
module Commands
|
8
|
-
|
9
|
-
def move(db)
|
10
|
-
redis.move rediskey, db
|
11
|
-
end
|
12
|
-
|
13
|
-
def rename(newkey)
|
14
|
-
redis.rename rediskey, newkey
|
15
|
-
end
|
16
|
-
|
17
|
-
def renamenx(newkey)
|
18
|
-
redis.renamenx rediskey, newkey
|
19
|
-
end
|
20
|
-
|
21
|
-
def type
|
22
|
-
redis.type rediskey
|
23
|
-
end
|
24
|
-
|
25
|
-
# Deletes the entire Redis key
|
26
|
-
# @return [Boolean] true if the key was deleted, false otherwise
|
27
|
-
def delete!
|
28
|
-
Familia.trace :DELETE!, redis, redisuri, caller(1..1) if Familia.debug?
|
29
|
-
ret = redis.del rediskey
|
30
|
-
ret.positive?
|
31
|
-
end
|
32
|
-
alias clear delete!
|
33
|
-
|
34
|
-
def exists?
|
35
|
-
redis.exists(rediskey) && !size.zero?
|
36
|
-
end
|
37
|
-
|
38
|
-
def realttl
|
39
|
-
redis.ttl rediskey
|
40
|
-
end
|
41
|
-
|
42
|
-
def expire(sec)
|
43
|
-
redis.expire rediskey, sec.to_i
|
44
|
-
end
|
45
|
-
|
46
|
-
def expireat(unixtime)
|
47
|
-
redis.expireat rediskey, unixtime
|
48
|
-
end
|
49
|
-
|
50
|
-
def persist
|
51
|
-
redis.persist rediskey
|
52
|
-
end
|
53
|
-
|
54
|
-
def echo(meth, trace)
|
55
|
-
redis.echo "[#{self.class}\##{meth}] #{trace} (#{@opts[:class]}\#)"
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|