typed_cache 0.1.1 → 0.2.0
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
- checksums.yaml.gz.sig +0 -0
- data/README.md +116 -19
- data/examples.md +106 -50
- data/lib/typed_cache/backends/memory.rb +9 -6
- data/lib/typed_cache/backends.rb +6 -8
- data/lib/typed_cache/cache_builder.rb +72 -19
- data/lib/typed_cache/cache_key.rb +2 -0
- data/lib/typed_cache/cache_ref.rb +4 -0
- data/lib/typed_cache/clock.rb +31 -14
- data/lib/typed_cache/decorator.rb +17 -0
- data/lib/typed_cache/{store → decorators}/instrumented.rb +19 -23
- data/lib/typed_cache/decorators.rb +7 -3
- data/lib/typed_cache/errors.rb +9 -1
- data/lib/typed_cache/instrumenter.rb +43 -0
- data/lib/typed_cache/instrumenters/active_support.rb +28 -0
- data/lib/typed_cache/instrumenters/mixins/namespaced_singleton.rb +52 -0
- data/lib/typed_cache/instrumenters/mixins.rb +8 -0
- data/lib/typed_cache/instrumenters/monitor.rb +27 -0
- data/lib/typed_cache/instrumenters/null.rb +26 -0
- data/lib/typed_cache/instrumenters.rb +38 -0
- data/lib/typed_cache/registry.rb +15 -0
- data/lib/typed_cache/store.rb +3 -0
- data/lib/typed_cache/version.rb +1 -1
- data/lib/typed_cache.rb +30 -14
- data/sig/generated/typed_cache/backends.rbs +2 -0
- data/sig/generated/typed_cache/cache_builder.rbs +13 -2
- data/sig/generated/typed_cache/clock.rbs +19 -9
- data/sig/generated/typed_cache/decorator.rbs +8 -0
- data/sig/generated/typed_cache/decorators/instrumented.rbs +35 -0
- data/sig/generated/typed_cache/decorators.rbs +2 -0
- data/sig/generated/typed_cache/errors.rbs +2 -0
- data/sig/generated/typed_cache/instrumenter.rbs +31 -0
- data/sig/generated/typed_cache/instrumenters/active_support.rbs +20 -0
- data/sig/generated/typed_cache/instrumenters/mixins/namespaced_singleton.rbs +33 -0
- data/sig/generated/typed_cache/instrumenters/mixins.rbs +8 -0
- data/sig/generated/typed_cache/instrumenters/monitor.rbs +19 -0
- data/sig/generated/typed_cache/instrumenters/null.rbs +21 -0
- data/sig/generated/typed_cache/instrumenters.rbs +24 -0
- data/sig/generated/typed_cache/registry.rbs +8 -0
- data/sig/generated/typed_cache/store/instrumented.rbs +2 -6
- data/sig/generated/typed_cache/store.rbs +3 -0
- data/sig/generated/typed_cache.rbs +6 -6
- data/typed_cache.gemspec +4 -3
- data.tar.gz.sig +0 -0
- metadata +25 -27
- metadata.gz.sig +0 -0
- data/lib/typed_cache/instrumentation.rb +0 -112
- data/sig/generated/typed_cache/instrumentation.rbs +0 -30
- data/sig/handwritten/gems/zeitwerk/2.7/zeitwerk.rbs +0 -9
@@ -0,0 +1,35 @@
|
|
1
|
+
# Generated from lib/typed_cache/decorators/instrumented.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Decorator that adds instrumentation to any Store implementation
|
5
|
+
# This decorator can wrap any store to add ActiveSupport::Notifications
|
6
|
+
# @rbs generic V
|
7
|
+
class Decorators::Instrumented[V]
|
8
|
+
include Decorator[V]
|
9
|
+
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
attr_reader store: TypedCache::Store[V]
|
13
|
+
|
14
|
+
attr_reader instrumenter: Instrumenter
|
15
|
+
|
16
|
+
# @rbs (Symbol, ?operation: String) ?{ (*untyped, **untyped) -> String } -> void
|
17
|
+
private def self.instrument: (Symbol, ?operation: String) ?{ (*untyped, **untyped) -> String } -> void
|
18
|
+
|
19
|
+
# : (TypedCache::Store[V], instrumenter: Instrumenter) -> void
|
20
|
+
def initialize: (TypedCache::Store[V], instrumenter: Instrumenter) -> void
|
21
|
+
|
22
|
+
# @rbs override
|
23
|
+
# : -> String
|
24
|
+
def store_type: ...
|
25
|
+
|
26
|
+
# @rbs override
|
27
|
+
# @rbs (key) -> CacheRef[V]
|
28
|
+
def ref: ...
|
29
|
+
|
30
|
+
# Additional methods that might exist on the wrapped store
|
31
|
+
def respond_to_missing?: (untyped method_name, ?untyped include_private) -> untyped
|
32
|
+
|
33
|
+
def method_missing: (untyped method_name, *untyped args) ?{ (?) -> untyped } -> untyped
|
34
|
+
end
|
35
|
+
end
|
@@ -13,12 +13,14 @@ module TypedCache
|
|
13
13
|
# .with_decorator(:my_decorator)
|
14
14
|
# .build.value
|
15
15
|
module Decorators
|
16
|
+
# @api private
|
16
17
|
# Default decorator set – starts with instrumentation only, but this registry
|
17
18
|
# lets end-users register their own via `Decorators.register`.
|
18
19
|
REGISTRY: untyped
|
19
20
|
|
20
21
|
extend Forwardable
|
21
22
|
|
23
|
+
# @api private
|
22
24
|
# @rbs () -> Registry[Store[untyped]]
|
23
25
|
def self.registry: () -> Registry[Store[untyped]]
|
24
26
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Generated from lib/typed_cache/instrumenter.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
# Instrumenter for cache operations
|
5
|
+
module Instrumenter
|
6
|
+
type event = Dry::Events::Event | ActiveSupport::Notifications::Event
|
7
|
+
|
8
|
+
# @rbs [R](String, String, **untyped) { -> R } -> R
|
9
|
+
def instrument: [R] (String, String, **untyped) { () -> R } -> R
|
10
|
+
|
11
|
+
# @rbs (String, **untyped) { (event) -> void } -> void
|
12
|
+
def subscribe: (String, **untyped) { (event) -> void } -> void
|
13
|
+
|
14
|
+
# : -> String
|
15
|
+
def namespace: () -> String
|
16
|
+
|
17
|
+
# @rbs (String, String, **untyped) -> Hash[Symbol, untyped]
|
18
|
+
def build_payload: (String, String, **untyped) -> Hash[Symbol, untyped]
|
19
|
+
|
20
|
+
# @rbs () -> bool
|
21
|
+
def enabled?: () -> bool
|
22
|
+
|
23
|
+
# @rbs (String) -> String
|
24
|
+
def event_name: (String) -> String
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# @rbs () -> TypedCache::_TypedCacheInstrumentationConfig
|
29
|
+
def config: () -> TypedCache::_TypedCacheInstrumentationConfig
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Generated from lib/typed_cache/instrumenters/active_support.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
module Instrumenters
|
5
|
+
# Instrumenter for ActiveSupport::Notifications
|
6
|
+
class ActiveSupport
|
7
|
+
include Instrumenter
|
8
|
+
|
9
|
+
include Mixins::NamespacedSingleton
|
10
|
+
|
11
|
+
# @rbs override
|
12
|
+
# : [R] (String, String, Hash[Symbol, untyped]) { -> R } -> R
|
13
|
+
def instrument: ...
|
14
|
+
|
15
|
+
# @rbs override
|
16
|
+
# @rbs (String, **top) { (event) -> void } -> void
|
17
|
+
def subscribe: ...
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Generated from lib/typed_cache/instrumenters/mixins/namespaced_singleton.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
module Instrumenters
|
5
|
+
module Mixins
|
6
|
+
module NamespacedSingleton
|
7
|
+
# @rbs () -> Array[Class[Instrumenter & NamespacedSingleton]]
|
8
|
+
def self.all: () -> Array[Class[Instrumenter & NamespacedSingleton]]
|
9
|
+
|
10
|
+
# @rbs (Class[Instrumenter & NamespacedSingleton]) -> void
|
11
|
+
def self.included: (Class[Instrumenter & NamespacedSingleton]) -> void
|
12
|
+
|
13
|
+
# @rbs override
|
14
|
+
# @rbs () -> String
|
15
|
+
def namespace: ...
|
16
|
+
|
17
|
+
# @rbs (String | Namespace) -> void
|
18
|
+
def initialize: (String | Namespace) -> void
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
# @rbs (String | Namespace) -> class
|
22
|
+
def new: (String | Namespace) -> class
|
23
|
+
|
24
|
+
# @rbs (String) -> maybe[class]
|
25
|
+
def get: (String) -> maybe[class]
|
26
|
+
|
27
|
+
# @rbs () -> Concurrent::Map[String, Class[Instrumenter & NamespacedSingleton]]
|
28
|
+
def namespace_cache: () -> Concurrent::Map[String, Class[Instrumenter & NamespacedSingleton]]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Generated from lib/typed_cache/instrumenters/monitor.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
module Instrumenters
|
5
|
+
class Monitor
|
6
|
+
include Instrumenter
|
7
|
+
|
8
|
+
include Mixins::NamespacedSingleton
|
9
|
+
|
10
|
+
# @rbs override
|
11
|
+
# : [R] (String, String, **untyped) { -> R } -> R
|
12
|
+
def instrument: ...
|
13
|
+
|
14
|
+
# @rbs override
|
15
|
+
# @rbs (String, **top) { (event) -> void } -> void
|
16
|
+
def subscribe: ...
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Generated from lib/typed_cache/instrumenters/null.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
module Instrumenters
|
5
|
+
# A no-op implementation used when instrumentation is disabled.
|
6
|
+
# It fulfils the Instrumenter contract but simply yields.
|
7
|
+
class Null
|
8
|
+
include Instrumenter
|
9
|
+
|
10
|
+
include Mixins::NamespacedSingleton
|
11
|
+
|
12
|
+
# @rbs override
|
13
|
+
# [R] (String, String, **untyped) { -> R } -> R
|
14
|
+
def instrument: ...
|
15
|
+
|
16
|
+
# @rbs override
|
17
|
+
# @rbs (String, **top) { (event) -> void } -> void
|
18
|
+
def subscribe: ...
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Generated from lib/typed_cache/instrumenters.rb with RBS::Inline
|
2
|
+
|
3
|
+
module TypedCache
|
4
|
+
module Instrumenters
|
5
|
+
# @api private
|
6
|
+
# Registry mapping symbols to instrumenter classes. We can't reuse the generic
|
7
|
+
# Registry class directly because many instrumenters mix in `Singleton`,
|
8
|
+
# making `.new` inaccessible. Instead we implement a thin facade that
|
9
|
+
# returns either the singleton instance (preferred) or a fresh instance.
|
10
|
+
REGISTRY: Registry[Symbol, Class[Instrumenter]]
|
11
|
+
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
# @api private
|
15
|
+
# @rbs () -> Registry[Symbol, Class[Instrumenter]]
|
16
|
+
def self.registry: () -> Registry[Symbol, Class[Instrumenter]]
|
17
|
+
|
18
|
+
def resolve: (Symbol, **untyped) -> either[Error, Instrumenter]
|
19
|
+
|
20
|
+
def available: () -> Array[Symbol]
|
21
|
+
|
22
|
+
def registered?: (Symbol) -> Boolean
|
23
|
+
end
|
24
|
+
end
|
@@ -7,6 +7,12 @@ module TypedCache
|
|
7
7
|
# @rbs (String, Hash[Symbol, Class[T]]) -> void
|
8
8
|
def initialize: (String, Hash[Symbol, Class[T]]) -> void
|
9
9
|
|
10
|
+
# @rbs (Registry[T]) -> Registry[T]
|
11
|
+
def initialize_copy: (Registry[T]) -> Registry[T]
|
12
|
+
|
13
|
+
# @rbs () -> void
|
14
|
+
def clear: () -> void
|
15
|
+
|
10
16
|
# @rbs (Symbol, *untyped, **untyped) -> either[Error, T]
|
11
17
|
def resolve: (Symbol, *untyped, **untyped) -> either[Error, T]
|
12
18
|
|
@@ -21,5 +27,7 @@ module TypedCache
|
|
21
27
|
|
22
28
|
# @rbs (Symbol) -> bool
|
23
29
|
def registered?: (Symbol) -> bool
|
30
|
+
|
31
|
+
attr_reader registry: Hash[Symbol, Class[T]]
|
24
32
|
end
|
25
33
|
end
|
@@ -14,8 +14,8 @@ module TypedCache
|
|
14
14
|
# @rbs (Symbol, ?operation: String) ?{ (*untyped, **untyped) -> String } -> void
|
15
15
|
private def self.instrument: (Symbol, ?operation: String) ?{ (*untyped, **untyped) -> String } -> void
|
16
16
|
|
17
|
-
# : (TypedCache::Store[V]) -> void
|
18
|
-
def initialize: (TypedCache::Store[V]) -> void
|
17
|
+
# : (TypedCache::Store[V], instrumenter: Instrumenter) -> void
|
18
|
+
def initialize: (TypedCache::Store[V], instrumenter: Instrumenter) -> void
|
19
19
|
|
20
20
|
# @rbs override
|
21
21
|
# : -> String
|
@@ -25,10 +25,6 @@ module TypedCache
|
|
25
25
|
# : -> String
|
26
26
|
def store_type: ...
|
27
27
|
|
28
|
-
# @rbs override
|
29
|
-
# : (cache_key) -> either[Error, CacheRef[V]]
|
30
|
-
def ref: ...
|
31
|
-
|
32
28
|
# Additional methods that might exist on the wrapped store
|
33
29
|
def respond_to_missing?: (untyped method_name, ?untyped include_private) -> untyped
|
34
30
|
|
@@ -72,6 +72,9 @@ module TypedCache
|
|
72
72
|
# @rbs (cache_key) { () -> V } -> either[Error, Snapshot[V]]
|
73
73
|
def fetch: (cache_key) { () -> V } -> either[Error, Snapshot[V]]
|
74
74
|
|
75
|
+
# @rbs () -> Instrumenter
|
76
|
+
def instrumenter: () -> Instrumenter
|
77
|
+
|
75
78
|
# Returns the namespace for this store (for instrumentation/debugging)
|
76
79
|
# @rbs () -> Namespace
|
77
80
|
def namespace: () -> Namespace
|
@@ -23,12 +23,12 @@ module TypedCache
|
|
23
23
|
|
24
24
|
def config: () -> _TypedCacheConfig
|
25
25
|
|
26
|
-
# @rbs () -> singleton(
|
27
|
-
def self.
|
26
|
+
# @rbs () -> singleton(Backends)
|
27
|
+
def self.backends: () -> singleton(Backends)
|
28
28
|
|
29
|
-
# @rbs () ->
|
30
|
-
def self.
|
29
|
+
# @rbs () -> singleton(Decorators)
|
30
|
+
def self.decorators: () -> singleton(Decorators)
|
31
31
|
|
32
|
-
# @rbs () ->
|
33
|
-
def self.
|
32
|
+
# @rbs () -> singleton(Instrumenters)
|
33
|
+
def self.instrumenters: () -> singleton(Instrumenters)
|
34
34
|
end
|
data/typed_cache.gemspec
CHANGED
@@ -29,13 +29,14 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.cert_chain = [Gem.default_cert_path]
|
30
30
|
|
31
31
|
spec.required_ruby_version = '>= 3.2.0'
|
32
|
-
|
33
|
-
spec.add_dependency('concurrent-ruby
|
32
|
+
|
33
|
+
spec.add_dependency('concurrent-ruby', '~> 1.0')
|
34
|
+
|
34
35
|
spec.add_dependency('dry-configurable', '~> 1.0')
|
36
|
+
spec.add_dependency('dry-monitor', '~>1.0')
|
35
37
|
spec.add_dependency('dry-struct', '~> 1.0')
|
36
38
|
spec.add_dependency('dry-types', '~>1.0')
|
37
39
|
spec.add_dependency('multi_json', '~> 1.17')
|
38
|
-
spec.add_dependency('zeitwerk', '~> 2.7')
|
39
40
|
|
40
41
|
spec.extra_rdoc_files = Dir['README*', 'LICENSE*', 'examples*']
|
41
42
|
spec.files = Dir['*.gemspec', 'lib/**/*', 'sig/**/*']
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typed_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Autumn Winter
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
uuhUq525FXA3gYeLAfnCSHNm7D1H7whsXYd3z+gKvEhSEQPb3mSBQ+31TDFmA5k7
|
36
36
|
q7YL3dwhxKPXtnAboI+30XBImpdizFG9Nyqgzgj/kD0QwVzL0QsVdVWnNTJXrm4n
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2025-
|
38
|
+
date: 2025-08-06 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: concurrent-ruby
|
@@ -43,30 +43,30 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 1.
|
46
|
+
version: '1.0'
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 1.
|
53
|
+
version: '1.0'
|
54
54
|
- !ruby/object:Gem::Dependency
|
55
|
-
name:
|
55
|
+
name: dry-configurable
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0
|
60
|
+
version: '1.0'
|
61
61
|
type: :runtime
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: 0
|
67
|
+
version: '1.0'
|
68
68
|
- !ruby/object:Gem::Dependency
|
69
|
-
name: dry-
|
69
|
+
name: dry-monitor
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
72
|
- - "~>"
|
@@ -121,20 +121,6 @@ dependencies:
|
|
121
121
|
- - "~>"
|
122
122
|
- !ruby/object:Gem::Version
|
123
123
|
version: '1.17'
|
124
|
-
- !ruby/object:Gem::Dependency
|
125
|
-
name: zeitwerk
|
126
|
-
requirement: !ruby/object:Gem::Requirement
|
127
|
-
requirements:
|
128
|
-
- - "~>"
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
version: '2.7'
|
131
|
-
type: :runtime
|
132
|
-
prerelease: false
|
133
|
-
version_requirements: !ruby/object:Gem::Requirement
|
134
|
-
requirements:
|
135
|
-
- - "~>"
|
136
|
-
- !ruby/object:Gem::Version
|
137
|
-
version: '2.7'
|
138
124
|
description: |
|
139
125
|
TypedCache is a Ruby caching library designed to eliminate common caching pitfalls by providing a monadic, type-safe API that makes cache operations explicit and predictable. Cache interactions are first-class operations with
|
140
126
|
comprehensive error handling and transparent state management. The library supports wrapping other caching libraries via custom backends and ActiveSupport::Cache is supported out of the box.
|
@@ -161,15 +147,21 @@ files:
|
|
161
147
|
- lib/typed_cache/clock.rb
|
162
148
|
- lib/typed_cache/decorator.rb
|
163
149
|
- lib/typed_cache/decorators.rb
|
150
|
+
- lib/typed_cache/decorators/instrumented.rb
|
164
151
|
- lib/typed_cache/either.rb
|
165
152
|
- lib/typed_cache/errors.rb
|
166
|
-
- lib/typed_cache/
|
153
|
+
- lib/typed_cache/instrumenter.rb
|
154
|
+
- lib/typed_cache/instrumenters.rb
|
155
|
+
- lib/typed_cache/instrumenters/active_support.rb
|
156
|
+
- lib/typed_cache/instrumenters/mixins.rb
|
157
|
+
- lib/typed_cache/instrumenters/mixins/namespaced_singleton.rb
|
158
|
+
- lib/typed_cache/instrumenters/monitor.rb
|
159
|
+
- lib/typed_cache/instrumenters/null.rb
|
167
160
|
- lib/typed_cache/maybe.rb
|
168
161
|
- lib/typed_cache/namespace.rb
|
169
162
|
- lib/typed_cache/registry.rb
|
170
163
|
- lib/typed_cache/snapshot.rb
|
171
164
|
- lib/typed_cache/store.rb
|
172
|
-
- lib/typed_cache/store/instrumented.rb
|
173
165
|
- lib/typed_cache/version.rb
|
174
166
|
- sig/generated/typed_cache.rbs
|
175
167
|
- sig/generated/typed_cache/backend.rbs
|
@@ -182,9 +174,16 @@ files:
|
|
182
174
|
- sig/generated/typed_cache/clock.rbs
|
183
175
|
- sig/generated/typed_cache/decorator.rbs
|
184
176
|
- sig/generated/typed_cache/decorators.rbs
|
177
|
+
- sig/generated/typed_cache/decorators/instrumented.rbs
|
185
178
|
- sig/generated/typed_cache/either.rbs
|
186
179
|
- sig/generated/typed_cache/errors.rbs
|
187
|
-
- sig/generated/typed_cache/
|
180
|
+
- sig/generated/typed_cache/instrumenter.rbs
|
181
|
+
- sig/generated/typed_cache/instrumenters.rbs
|
182
|
+
- sig/generated/typed_cache/instrumenters/active_support.rbs
|
183
|
+
- sig/generated/typed_cache/instrumenters/mixins.rbs
|
184
|
+
- sig/generated/typed_cache/instrumenters/mixins/namespaced_singleton.rbs
|
185
|
+
- sig/generated/typed_cache/instrumenters/monitor.rbs
|
186
|
+
- sig/generated/typed_cache/instrumenters/null.rbs
|
188
187
|
- sig/generated/typed_cache/maybe.rbs
|
189
188
|
- sig/generated/typed_cache/namespace.rbs
|
190
189
|
- sig/generated/typed_cache/registry.rbs
|
@@ -192,14 +191,13 @@ files:
|
|
192
191
|
- sig/generated/typed_cache/store.rbs
|
193
192
|
- sig/generated/typed_cache/store/instrumented.rbs
|
194
193
|
- sig/generated/typed_cache/version.rbs
|
195
|
-
- sig/handwritten/gems/zeitwerk/2.7/zeitwerk.rbs
|
196
194
|
- typed_cache.gemspec
|
197
195
|
homepage: https://github.com/glossawy/typed_cache
|
198
196
|
licenses:
|
199
197
|
- Apache-2.0
|
200
198
|
metadata:
|
201
199
|
issue_tracker_uri: https://github.com/glossawy/typed_cache/issues
|
202
|
-
changelog_uri: https://github.com/glossawy/typed_cache/blob/main/VERSIONS.adoc#
|
200
|
+
changelog_uri: https://github.com/glossawy/typed_cache/blob/main/VERSIONS.adoc#020
|
203
201
|
license_uri: https://github.com/glossawy/typed_cache/blob/main/LICENSE
|
204
202
|
label: caching
|
205
203
|
labels: typed_cache,ruby,caching,type-safety,rails,rbs
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,112 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'dry/configurable'
|
4
|
-
|
5
|
-
module TypedCache
|
6
|
-
# Instrumentation hooks for ActiveSupport::Notifications integration
|
7
|
-
# All instrumentation is explicit and opt-in - no automatic behavior
|
8
|
-
module Instrumentation
|
9
|
-
class << self
|
10
|
-
# @rbs! type config = TypedCache::_TypedCacheInstrumentationConfig
|
11
|
-
|
12
|
-
# @rbs () -> config
|
13
|
-
def config
|
14
|
-
TypedCache.config.instrumentation
|
15
|
-
end
|
16
|
-
|
17
|
-
# Check if ActiveSupport::Notifications is available
|
18
|
-
# @rbs () -> bool
|
19
|
-
def notifications_available?
|
20
|
-
defined?(ActiveSupport::Notifications)
|
21
|
-
end
|
22
|
-
|
23
|
-
# Main instrumentation method
|
24
|
-
#: [T] (String, String, String, Hash[Symbol, untyped]) { -> T } -> T
|
25
|
-
def instrument(operation, namespace, key, payload = {})
|
26
|
-
return yield unless config.enabled && notifications_available?
|
27
|
-
|
28
|
-
event_name = "#{operation}.#{config.namespace}"
|
29
|
-
start_time = current_time
|
30
|
-
|
31
|
-
begin
|
32
|
-
result = yield
|
33
|
-
|
34
|
-
# Determine success and extract metadata
|
35
|
-
success, snapshot_data = extract_result_metadata(result)
|
36
|
-
|
37
|
-
final_payload = base_payload(namespace, key, start_time).merge(payload).merge({
|
38
|
-
success: success,
|
39
|
-
**snapshot_data,
|
40
|
-
})
|
41
|
-
|
42
|
-
ActiveSupport::Notifications.instrument(event_name, final_payload) do
|
43
|
-
# This block is called by subscribers who want the result
|
44
|
-
result
|
45
|
-
end
|
46
|
-
|
47
|
-
result
|
48
|
-
rescue => error
|
49
|
-
error_payload = base_payload(namespace, key, start_time).merge(payload).merge({
|
50
|
-
success: false,
|
51
|
-
error: error.class.name,
|
52
|
-
error_message: error.message,
|
53
|
-
})
|
54
|
-
|
55
|
-
ActiveSupport::Notifications.instrument(event_name, error_payload)
|
56
|
-
raise
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
# Cross-platform current time helper (uses Time.current when available)
|
63
|
-
#: -> Time
|
64
|
-
def current_time
|
65
|
-
if Time.respond_to?(:current)
|
66
|
-
Time.current
|
67
|
-
else
|
68
|
-
Time.now
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# @rbs (String, String, Time) -> Hash[Symbol, untyped]
|
73
|
-
def base_payload(namespace, key, start_time)
|
74
|
-
{
|
75
|
-
namespace: namespace,
|
76
|
-
key: key,
|
77
|
-
duration: (current_time - start_time) * 1000.0, # milliseconds
|
78
|
-
store_type: nil, # Will be set by caller if available
|
79
|
-
}
|
80
|
-
end
|
81
|
-
|
82
|
-
# @rbs (Either[StandardError, Snapshot]) -> [bool, Hash[Symbol, untyped]]
|
83
|
-
def extract_result_metadata(result)
|
84
|
-
case result
|
85
|
-
when Either
|
86
|
-
if result.right?
|
87
|
-
snapshot = result.value
|
88
|
-
if snapshot.is_a?(Snapshot)
|
89
|
-
[true, {
|
90
|
-
cache_hit: snapshot.from_cache?,
|
91
|
-
cache_miss: !snapshot.from_cache?,
|
92
|
-
source: snapshot.source,
|
93
|
-
snapshot_age: snapshot.age,
|
94
|
-
},]
|
95
|
-
else
|
96
|
-
[true, { cache_hit: false, cache_miss: true }]
|
97
|
-
end
|
98
|
-
else
|
99
|
-
error_data = {
|
100
|
-
cache_hit: false,
|
101
|
-
cache_miss: true,
|
102
|
-
error_type: result.error.class.name,
|
103
|
-
}
|
104
|
-
[false, error_data]
|
105
|
-
end
|
106
|
-
else
|
107
|
-
[true, {}]
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# Generated from lib/typed_cache/instrumentation.rb with RBS::Inline
|
2
|
-
|
3
|
-
module TypedCache
|
4
|
-
# Instrumentation hooks for ActiveSupport::Notifications integration
|
5
|
-
# All instrumentation is explicit and opt-in - no automatic behavior
|
6
|
-
module Instrumentation
|
7
|
-
type config = TypedCache::_TypedCacheInstrumentationConfig
|
8
|
-
|
9
|
-
# @rbs () -> config
|
10
|
-
def self.config: () -> config
|
11
|
-
|
12
|
-
# Check if ActiveSupport::Notifications is available
|
13
|
-
# @rbs () -> bool
|
14
|
-
def self.notifications_available?: () -> bool
|
15
|
-
|
16
|
-
# Main instrumentation method
|
17
|
-
# : [T] (String, String, String, Hash[Symbol, untyped]) { -> T } -> T
|
18
|
-
def self.instrument: [T] (String, String, String, Hash[Symbol, untyped]) { () -> T } -> T
|
19
|
-
|
20
|
-
# Cross-platform current time helper (uses Time.current when available)
|
21
|
-
# : -> Time
|
22
|
-
private def self.current_time: () -> Time
|
23
|
-
|
24
|
-
# @rbs (String, String, Time) -> Hash[Symbol, untyped]
|
25
|
-
private def self.base_payload: (String, String, Time) -> Hash[Symbol, untyped]
|
26
|
-
|
27
|
-
# @rbs (Either[StandardError, Snapshot]) -> [bool, Hash[Symbol, untyped]]
|
28
|
-
private def self.extract_result_metadata: (Either[StandardError, Snapshot]) -> [ bool, Hash[Symbol, untyped] ]
|
29
|
-
end
|
30
|
-
end
|