network_resiliency 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b75b4aad26c41942f4d38ad70abb82d8f098eb377e9e5f44d1f6dde41ab6225
4
- data.tar.gz: 47c899a650d66cea1117743ce4b53ee7bc50cc4fef8dfca3337aa071d0f81964
3
+ metadata.gz: b26da5cafa1321e4b284d8b3ade1184d4423973f388b1e4288b3be3d79153c3b
4
+ data.tar.gz: 6a4588995b8fdab21e424235bb31d2d83bef8d6b43d2b4ab1f9f3e9df08e19cf
5
5
  SHA512:
6
- metadata.gz: ef7d805366f84daf7a27f5fb6dc88ef846741456203fa23f30512d780ae46065b5519caa474e7750b260e2a9bca5b9e296cb4def7e60402cfabdf0ae4aa1bf7c
7
- data.tar.gz: 11d564818a9700a685c8d3dc9873de64181079fffffcbc0dd192d2ddbb47f0b75e43e92ba08d4523376a0a617ba60c9dd599e07fce1c055e48398b38f2e40ee3
6
+ metadata.gz: d6b110ad5631918d1077f4ba77a63da113fa9b19f156f439f6b46a2f8817d770740e157d07d7752b443568b3d1f86f416ff707d3ff0598a71b0355dabf1aa0c8
7
+ data.tar.gz: ab91f3ac1febb0504b8b0a64f0f12014636fd86bfc1ea3f1c1904a38660b8be791cc07835fed7154775d150bbc131243f4e892e255ecd7a96f68dbd7d1cd637a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### v0.2.0 (2023-10-01)
2
+ - high level patch
3
+ - redis adapter
4
+ - mock redis
5
+ - freeze time in specs
6
+
1
7
  ### v0.1.1 (2023-09-27)
2
8
  - prevent double patching
3
9
  - filter ip addresses
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- network_resiliency (0.1.1)
4
+ network_resiliency (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -6,6 +6,8 @@ module NetworkResiliency
6
6
  extend self
7
7
 
8
8
  def patch(instance = nil)
9
+ return if patched?(instance)
10
+
9
11
  (instance&.singleton_class || Net::HTTP).prepend(Instrumentation)
10
12
  end
11
13
 
@@ -3,61 +3,73 @@ require "redis"
3
3
  module NetworkResiliency
4
4
  module Adapter
5
5
  module Redis
6
- def connect(redis_config)
7
- puts "RedisClient.connect(#{client.connect_timeout})"
6
+ extend self
8
7
 
9
- old_timeout = client.connect_timeout
8
+ def patch(instance = nil)
9
+ return if patched?(instance)
10
10
 
11
- already_connected = client.connected?
11
+ if instance
12
+ unless instance.is_a?(::Redis)
13
+ raise ArgumentError, "expected Redis instance, found: #{instance}"
14
+ end
12
15
 
13
- # client.connect_timeout = 0.1
14
- ts = -NetworkResiliency.timestamp
15
- super
16
- ensure
17
- client.connect_timeout = old_timeout
16
+ client = instance.instance_variable_get(:@client)
18
17
 
19
- ts += NetworkResiliency.timestamp
18
+ unless client.is_a?(::Redis::Client)
19
+ raise ArgumentError, "unsupported Redis client: #{client}"
20
+ end
20
21
 
21
- note = already_connected ? " (already_connected)" : ""
22
+ client.singleton_class.prepend(Instrumentation)
23
+ else
24
+ ::Redis::Client.prepend(Instrumentation)
25
+ end
26
+ end
27
+
28
+ def patched?(instance = nil)
29
+ if instance
30
+ client = instance.instance_variable_get(:@client)
22
31
 
23
- puts "connect time: #{ts}#{note}"
32
+ client && client.singleton_class.ancestors.include?(Instrumentation)
33
+ else
34
+ ::Redis::Client.ancestors.include?(Instrumentation)
35
+ end
24
36
  end
25
37
 
26
- def call(command, redis_config)
27
- puts "RedisClient.call"
38
+ module Instrumentation
39
+ # def initialize(...)
40
+ # super
28
41
 
29
- key = "#{id}:call"
30
- ts = -NetworkResiliency.timestamp
31
- with_timeout(1) { super }
32
- ensure
33
- ts += NetworkResiliency.timestamp
34
- puts "call time: #{ts}"
42
+ # @network_resiliency_attempts = options[:reconnect_attempts]
43
+ # options[:reconnect_attempts] = 0
44
+ # end
35
45
 
36
- NetworkResiliency.record(self, id, ts)
37
- end
46
+ def establish_connection
47
+ return super unless NetworkResiliency.enabled?(:redis)
38
48
 
39
- def id
40
- "redis:#{client.host}"
41
- end
49
+ begin
50
+ ts = -NetworkResiliency.timestamp
42
51
 
43
- def with_timeout(timeout)
44
- old_timeouts = [
45
- client.connect_timeout,
46
- client.read_timeout,
47
- client.write_timeout,
48
- ]
52
+ super
53
+ rescue ::Redis::CannotConnectError => e
54
+ # capture error
55
+ raise
56
+ ensure
57
+ ts += NetworkResiliency.timestamp
49
58
 
50
- client.connect_timeout = timeout
51
- client.read_timeout = timeout
52
- client.write_timeout = timeout
59
+ # grab underlying exception within Redis wrapper
60
+ error = e ? e.cause.class : nil
53
61
 
54
- yield
55
- ensure
56
- client.connect_timeout, client.read_timeout, client.write_timeout = *old_timeouts
62
+ NetworkResiliency.record(
63
+ adapter: "redis",
64
+ action: "connect",
65
+ destination: host,
66
+ error: error,
67
+ duration: ts,
68
+ )
69
+ end
70
+ end
57
71
  end
58
72
  end
59
73
  end
60
74
  end
61
75
 
62
- # RedisClient.register(NetworkResiliency::Adapter::Redis)
63
- # Redis.new(middlewares: [NetworkResiliency::Adapter::Redis])
@@ -1,3 +1,3 @@
1
1
  module NetworkResiliency
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -15,10 +15,25 @@ module NetworkResiliency
15
15
  yield self
16
16
  end
17
17
 
18
+ def patch(*adapters)
19
+ adapters.each do |adapter|
20
+ case adapter
21
+ when :http
22
+ Adapter::HTTP.patch
23
+ when :redis
24
+ Adapter::Redis.patch
25
+ else
26
+ raise NotImplementedError
27
+ end
28
+ end
29
+ end
30
+
18
31
  def enabled?(adapter)
19
32
  return true if @enabled.nil?
20
33
 
21
- @enabled.is_a?(Proc) ? @enabled.call(adapter) : @enabled
34
+ @enabled.is_a?(Proc) ? !!@enabled.call(adapter) : @enabled
35
+ rescue
36
+ false
22
37
  end
23
38
 
24
39
  def enabled=(enabled)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: network_resiliency
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Pepper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-28 00:00:00.000000000 Z
11
+ date: 2023-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: byebug