semian 0.28.2 → 0.28.4
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/README.md +23 -1
- data/lib/semian/activerecord_adapter.rb +19 -1
- data/lib/semian/activerecord_postgresql_adapter.rb +5 -0
- data/lib/semian/adapter.rb +1 -2
- data/lib/semian/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8fa1376f607286da6a30b6db227b4b27281228308c9c68724b356189cc97d2fb
|
|
4
|
+
data.tar.gz: 05161e0480da351f89ee3c3fe40cc9d4527a20e64f7830fdf671f92057675bb5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22d2074bf889aae268ea568f4a95f43b8e27f7b02ff24f4bf4afdcddba98bdf01e9090b166bc1b0124667bce39f57f19b5933415a309779e86fe448d5b2f7a36
|
|
7
|
+
data.tar.gz: 0b7a495a4e7a0bf71fa87b7422c6076c0580b3e368c23d1418d1e8c92745d2ba5acf951a049ade3e2b780a30273ad08fcb30747df2de36d5535e5a002866a952
|
data/README.md
CHANGED
|
@@ -83,7 +83,8 @@ To create a Semian adapter you must implement the following methods:
|
|
|
83
83
|
1. [`include Semian::Adapter`][semian-adapter]. Use the helpers to wrap the
|
|
84
84
|
resource. This takes care of situations such as monitoring, nested resources,
|
|
85
85
|
unsupported platforms, creating the Semian resource if it doesn't already
|
|
86
|
-
exist and so on.
|
|
86
|
+
exist and so on. Include it in an object that represents a single resource,
|
|
87
|
+
typically one connection — see [Thread Safety](#thread-safety).
|
|
87
88
|
2. `#semian_identifier`. This is responsible for returning a symbol that
|
|
88
89
|
represents every unique resource, for example `redis_master` or
|
|
89
90
|
`mysql_shard_1`. This is usually assembled from a `name` attribute on the
|
|
@@ -214,6 +215,27 @@ Semian's circuit breaker implementation is thread-safe by default as of
|
|
|
214
215
|
`v0.7.0`. If you'd like to disable it for performance reasons, pass
|
|
215
216
|
`thread_safety_disabled: true` to the resource options.
|
|
216
217
|
|
|
218
|
+
An adapter instance represents one resource. Once that resource has been
|
|
219
|
+
acquired, Semian treats further access through the same instance as part of the
|
|
220
|
+
same session: nested or overlapping calls do not re-enter the circuit breaker
|
|
221
|
+
and do not take a second bulkhead ticket, so a circuit that opens elsewhere in
|
|
222
|
+
the process cannot interrupt a session that is already in flight and
|
|
223
|
+
succeeding. Every adapter that ships with Semian has this shape — the mixin is
|
|
224
|
+
included in a connection object, and the session is that connection's unit of
|
|
225
|
+
work.
|
|
226
|
+
|
|
227
|
+
This is likely to give unexpected results if the adapter instance is shared
|
|
228
|
+
process-wide, such as by a singleton. While any call is in flight, calls made
|
|
229
|
+
through the same instance from other threads are treated as part of that
|
|
230
|
+
session, so they are not fast-failed when the circuit has opened since that
|
|
231
|
+
first acquire, and they cannot contribute failures. Where calls overlap
|
|
232
|
+
continuously, that keeps the circuit closed while the resource is failing.
|
|
233
|
+
Consider introducing a "session" object as the adapterized wrapper around the
|
|
234
|
+
singleton instead, created per unit of work — per request, say. Circuit breaker
|
|
235
|
+
and bulkhead state is keyed by `semian_identifier` and held in a process-wide
|
|
236
|
+
registry, so short-lived adapter instances that share an identifier all share
|
|
237
|
+
one circuit.
|
|
238
|
+
|
|
217
239
|
Bulkheads should be disabled (pass `bulkhead: false`) in a threaded environment
|
|
218
240
|
(e.g. Puma or Sidekiq), but can safely be enabled in non-threaded environments
|
|
219
241
|
(e.g. Resque and Unicorn). As described in this document, circuit breakers alone
|
|
@@ -58,8 +58,26 @@ module Semian
|
|
|
58
58
|
def execute_intent(intent)
|
|
59
59
|
return super if self.class.query_allowlisted?(intent.processed_sql)
|
|
60
60
|
|
|
61
|
+
result = nil
|
|
62
|
+
delivered_error = nil
|
|
63
|
+
|
|
61
64
|
acquire_semian_resource(adapter: semian_adapter_name, scope: :query) do
|
|
62
|
-
super
|
|
65
|
+
result = super
|
|
66
|
+
|
|
67
|
+
# In Rails 8.2 execute_intent no longer raises errors. Instead, they are stored on the intent
|
|
68
|
+
# and handled later by the caller to better enable asynchronous execution. However, we need to raise
|
|
69
|
+
# any errors here to trip the circuit breaker. Then we can swallow the error and return the result for
|
|
70
|
+
# Rails to continue with.
|
|
71
|
+
if intent.respond_to?(:error)
|
|
72
|
+
delivered_error = intent.error
|
|
73
|
+
raise delivered_error if delivered_error
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
rescue => error
|
|
77
|
+
if error.equal?(delivered_error)
|
|
78
|
+
result
|
|
79
|
+
else
|
|
80
|
+
raise
|
|
63
81
|
end
|
|
64
82
|
end
|
|
65
83
|
else
|
|
@@ -7,6 +7,7 @@ module ActiveRecord
|
|
|
7
7
|
module ConnectionAdapters
|
|
8
8
|
class PostgreSQLAdapter
|
|
9
9
|
ActiveRecord::ActiveRecordError.include(::Semian::AdapterError)
|
|
10
|
+
::PG::ConnectionBad.include(::Semian::AdapterError)
|
|
10
11
|
|
|
11
12
|
class SemianError < ConnectionNotEstablished
|
|
12
13
|
def initialize(semian_identifier, *args)
|
|
@@ -40,6 +41,10 @@ module Semian
|
|
|
40
41
|
|
|
41
42
|
private
|
|
42
43
|
|
|
44
|
+
def resource_exceptions
|
|
45
|
+
super + [::PG::ConnectionBad]
|
|
46
|
+
end
|
|
47
|
+
|
|
43
48
|
def semian_adapter_name = :postgresql_adapter
|
|
44
49
|
|
|
45
50
|
def semian_adapter_default_port = 5432
|
data/lib/semian/adapter.rb
CHANGED
data/lib/semian/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: semian
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.28.
|
|
4
|
+
version: 0.28.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Scott Francis
|
|
@@ -100,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
100
100
|
- !ruby/object:Gem::Version
|
|
101
101
|
version: '0'
|
|
102
102
|
requirements: []
|
|
103
|
-
rubygems_version: 4.0.
|
|
103
|
+
rubygems_version: 4.0.19
|
|
104
104
|
specification_version: 4
|
|
105
105
|
summary: Bulkheading for Ruby with SysV semaphores
|
|
106
106
|
test_files: []
|