network_resiliency 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d085dba12da295ad4c4bb4d540acb3b865c8d8486b9bdf6d812e74430efcd55f
4
- data.tar.gz: 24d61f1205ecba15f7acbda327d91be3ca0c74dd0955c2fe03338f873435d478
3
+ metadata.gz: 07f28c3158ada0009efdc0d9b68162419d227d088b24b3827a43dc5923ca8081
4
+ data.tar.gz: 645bd61e91ac8b939713376de77cedcd1f79e254a558b0b09cd26ba0280abe68
5
5
  SHA512:
6
- metadata.gz: 91e9bcd5141345e0117be83f1e01951a11f6ffc8b100c1776a0ba3a2ac2bde19642369875ee79d995f8c4f3bbc0742f72c67102295bdecb2e9afd681597f555c
7
- data.tar.gz: df13161c53527c10143d7c11b56ac7cc2a75189eb58b2d698d2f9940dd50a894a3e6dae8680764a6773c68c6dc107faf8613b457c5edeb1dc7c65200fe97e491
6
+ metadata.gz: 47b0bbe65d83b4acad810673904a13d57c898a00193fb48432b690d31932d19e52d397363195917f9e3dd8b1631084bdfd193094e8f570fb914ab490db9fd544
7
+ data.tar.gz: dd8f225e3bcf5d597838e405fa8c80b7228fdc5aacdf326b38c9fdb0eae72eae60bf00e0be1eed970547014b5f820557635cfd6422741e91c0e6e2cc22935bc6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ### v0.1.0 (2023-09-26)
2
+ - rework faraday adapter
3
+ - faraday
4
+ - adapter scoped enabled
5
+ - scope rspec helper
6
+ - adapter tag
7
+ - enable disable block mode
8
+ - drop ruby 2.7 support
9
+ - resiliency
10
+ - pointer
11
+ - code coverage upgrade
12
+ - requirements
13
+ - http adapter
14
+ - mock http server
15
+ - add ddtrace to dev
16
+
1
17
  ### v0.0.2 (2023-05-09)
2
18
  - rename to Network Resiliency
3
19
  - fix sample variance
data/Gemfile.lock CHANGED
@@ -1,67 +1,90 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- network_resiliency (0.0.2)
5
- faraday
4
+ network_resiliency (0.1.0)
6
5
 
7
6
  GEM
8
7
  remote: https://rubygems.org/
9
8
  specs:
10
9
  byebug (11.1.3)
11
- codecov (0.5.2)
12
- simplecov (>= 0.15, < 0.22)
13
- connection_pool (2.3.0)
14
- diff-lcs (1.4.4)
10
+ ddtrace (1.14.0)
11
+ debase-ruby_core_source (= 3.2.1)
12
+ libdatadog (~> 3.0.0.1.0)
13
+ libddwaf (~> 1.9.0.0.0)
14
+ msgpack
15
+ debase-ruby_core_source (3.2.1)
16
+ diff-lcs (1.5.0)
15
17
  docile (1.4.0)
16
- faraday (2.7.4)
17
- faraday-net_http (>= 2.0, < 3.1)
18
+ dogstatsd-ruby (4.8.3)
19
+ faraday (1.10.3)
20
+ faraday-em_http (~> 1.0)
21
+ faraday-em_synchrony (~> 1.0)
22
+ faraday-excon (~> 1.1)
23
+ faraday-httpclient (~> 1.0)
24
+ faraday-multipart (~> 1.0)
25
+ faraday-net_http (~> 1.0)
26
+ faraday-net_http_persistent (~> 1.0)
27
+ faraday-patron (~> 1.0)
28
+ faraday-rack (~> 1.0)
29
+ faraday-retry (~> 1.0)
18
30
  ruby2_keywords (>= 0.0.4)
19
- faraday-net_http (3.0.2)
31
+ faraday-em_http (1.0.0)
32
+ faraday-em_synchrony (1.0.0)
33
+ faraday-excon (1.1.0)
34
+ faraday-httpclient (1.0.1)
35
+ faraday-multipart (1.0.4)
36
+ multipart-post (~> 2)
37
+ faraday-net_http (1.0.1)
38
+ faraday-net_http_persistent (1.2.0)
39
+ faraday-patron (1.0.0)
20
40
  faraday-rack (1.0.0)
21
- rack (3.0.2)
22
- rack-test (2.0.2)
41
+ faraday-retry (1.0.3)
42
+ ffi (1.15.5)
43
+ libdatadog (3.0.0.1.0)
44
+ libddwaf (1.9.0.0.1)
45
+ ffi (~> 1.0)
46
+ msgpack (1.7.2)
47
+ multipart-post (2.3.0)
48
+ rack (3.0.8)
49
+ rack-test (2.1.0)
23
50
  rack (>= 1.3)
24
- redis (5.0.5)
25
- redis-client (>= 0.9.0)
26
- redis-client (0.11.2)
27
- connection_pool
28
- rspec (3.10.0)
29
- rspec-core (~> 3.10.0)
30
- rspec-expectations (~> 3.10.0)
31
- rspec-mocks (~> 3.10.0)
32
- rspec-core (3.10.1)
33
- rspec-support (~> 3.10.0)
34
- rspec-expectations (3.10.1)
51
+ redis (4.8.1)
52
+ rspec (3.12.0)
53
+ rspec-core (~> 3.12.0)
54
+ rspec-expectations (~> 3.12.0)
55
+ rspec-mocks (~> 3.12.0)
56
+ rspec-core (3.12.2)
57
+ rspec-support (~> 3.12.0)
58
+ rspec-expectations (3.12.3)
35
59
  diff-lcs (>= 1.2.0, < 2.0)
36
- rspec-support (~> 3.10.0)
37
- rspec-mocks (3.10.2)
60
+ rspec-support (~> 3.12.0)
61
+ rspec-mocks (3.12.6)
38
62
  diff-lcs (>= 1.2.0, < 2.0)
39
- rspec-support (~> 3.10.0)
40
- rspec-support (3.10.2)
63
+ rspec-support (~> 3.12.0)
64
+ rspec-support (3.12.1)
41
65
  ruby2_keywords (0.0.5)
42
- simplecov (0.21.2)
66
+ simplecov (0.22.0)
43
67
  docile (~> 1.1)
44
68
  simplecov-html (~> 0.11)
45
69
  simplecov_json_formatter (~> 0.1)
46
70
  simplecov-html (0.12.3)
47
- simplecov_json_formatter (0.1.3)
71
+ simplecov_json_formatter (0.1.4)
48
72
 
49
73
  PLATFORMS
50
- x86_64-darwin-19
51
- x86_64-darwin-20
52
- x86_64-darwin-21
74
+ ruby
53
75
 
54
76
  DEPENDENCIES
55
77
  byebug
56
- codecov
78
+ ddtrace (>= 1)
79
+ dogstatsd-ruby (<= 4.8.3)
80
+ faraday (~> 1)
57
81
  faraday-rack
58
82
  network_resiliency!
59
83
  rack
60
84
  rack-test
61
- redis
62
- redis-client (>= 0.10)
85
+ redis (~> 4)
63
86
  rspec
64
87
  simplecov
65
88
 
66
89
  BUNDLED WITH
67
- 2.2.20
90
+ 2.4.19
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
- ApiAvenger
1
+ NetworkResiliency
2
2
  ======
3
- ...
3
+ ![Gem](https://img.shields.io/gem/dt/network_resiliency?style=plastic)
4
+ [![codecov](https://codecov.io/gh/dpep/network_resiliency_rb/branch/main/graph/badge.svg)](https://codecov.io/gh/dpep/network_resiliency_rb)
5
+
6
+ Making networks more resilient to errors.
7
+
8
+ Resiliency: the ability to recover from adversity or adjust to change.
4
9
 
5
10
 
6
11
  ```ruby
@@ -21,6 +26,10 @@ Yes please :)
21
26
  1. Create a Pull Request
22
27
 
23
28
 
29
+
24
30
  ----
25
- ![Gem](https://img.shields.io/gem/dt/network_resiliency?style=plastic)
26
- [![codecov](https://codecov.io/gh/dpep/network_resiliency_rb/branch/main/graph/badge.svg)](https://codecov.io/gh/dpep/network_resiliency_rb)
31
+ ### Inspired by
32
+
33
+ https://github.com/lostisland/faraday-retry/blob/main/lib/faraday/retry/middleware.rb
34
+
35
+ https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts
@@ -2,58 +2,16 @@ require "faraday"
2
2
 
3
3
  module NetworkResiliency
4
4
  module Adapter
5
- class Faraday < ::Faraday::Middleware
6
- def call(env)
7
- puts "NetworkResiliency called: #{env.url}"
8
- # env.options.timeout = 0.001
9
- # open_timeout
10
-
11
- # url => id
12
- # predict time
13
- # get dynamic timeout
14
-
15
- if NetworkResiliency.enabled?
16
- # temp update timeout
17
- # with_timeout(...) { super }
18
- else
19
- super
5
+ class Faraday < ::Faraday::Adapter::NetHttp
6
+ def build_connection(env)
7
+ super.tap do |conn|
8
+ NetworkResiliency::Adapter::HTTP.patch(conn)
20
9
  end
21
- rescue ::Faraday::Error => e
22
- # note exception for ensure block
23
- ensure
24
- # record time taken
25
-
26
- # reraise if applicable
27
- raise e if e
28
- end
29
-
30
- def normalized_id(env)
31
- env.url
32
- end
33
-
34
- def with_timeout(env, timeout)
35
- old_timeouts = [
36
- env.options.timeout,
37
- env.options.open_timeout,
38
- env.options.read_timeout,
39
- env.options.write_timeout,
40
- ]
41
-
42
- env.options.timeout = [
43
- env.options.timeout,
44
- timeout,
45
- ].compact.min
46
-
47
- # env.options.open_timeout = [ env.options.open_timeout, timeout ].compact.min
48
- # ...
49
- ensure
50
- env.options.timeout = old_timeouts[0]
51
- # ...
52
10
  end
53
11
  end
54
12
  end
55
13
  end
56
14
 
57
- Faraday::Request.register_middleware(
15
+ Faraday::Adapter.register_middleware(
58
16
  network_resiliency: NetworkResiliency::Adapter::Faraday,
59
17
  )
@@ -0,0 +1,44 @@
1
+ require "net/http"
2
+
3
+ module NetworkResiliency
4
+ module Adapter
5
+ module HTTP
6
+ extend self
7
+
8
+ def patch(instance = nil)
9
+ (instance&.singleton_class || Net::HTTP).prepend(Instrumentation)
10
+ end
11
+
12
+ def patched?(instance = nil)
13
+ (instance&.singleton_class || Net::HTTP).ancestors.include?(Instrumentation)
14
+ end
15
+
16
+ module Instrumentation
17
+ def connect
18
+ return super unless NetworkResiliency.enabled?(:http)
19
+
20
+ begin
21
+ ts = -NetworkResiliency.timestamp
22
+
23
+ super
24
+ rescue Net::OpenTimeout => e
25
+ # capture error
26
+ raise
27
+ ensure
28
+ ts += NetworkResiliency.timestamp
29
+
30
+ NetworkResiliency.statsd&.distribution(
31
+ "network_resiliency.connect",
32
+ ts,
33
+ tags: {
34
+ adapter: "http",
35
+ destination: address,
36
+ error: e&.class,
37
+ }.compact,
38
+ )
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -59,5 +59,5 @@ module NetworkResiliency
59
59
  end
60
60
  end
61
61
 
62
- # RedisClient.register(RedisAvenger)
63
- # Redis.new(middlewares: [RedisAvenger])
62
+ # RedisClient.register(NetworkResiliency::Adapter::Redis)
63
+ # Redis.new(middlewares: [NetworkResiliency::Adapter::Redis])
@@ -1,3 +1,3 @@
1
1
  module NetworkResiliency
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,123 +1,54 @@
1
- require "network_resiliency/stats"
2
1
  require "network_resiliency/version"
3
2
 
4
3
  module NetworkResiliency
5
- extend self
6
-
7
- def enabled?
8
- true
4
+ module Adapter
5
+ autoload :HTTP, "network_resiliency/adapter/http"
6
+ autoload :Faraday, "network_resiliency/adapter/faraday"
7
+ autoload :Redis, "network_resiliency/adapter/redis"
9
8
  end
10
9
 
11
- def sample?
12
- enabled? || rand < sample_rate
13
- end
10
+ extend self
14
11
 
15
- # def mode=(mode)
16
- # unless [ :avg, :x10, :sig1, :sig2, :sig3 ]
17
- # end
12
+ attr_accessor :statsd
18
13
 
19
- def timeout(adapter, key)
20
- stats = self.stats(adapter, key)
14
+ def enabled?(adapter)
15
+ return true if @enabled.nil?
21
16
 
22
- stats.avg * 10 if stats.n >= 100
17
+ @enabled.is_a?(Proc) ? @enabled.call(adapter) : @enabled
23
18
  end
24
19
 
25
- def stats(adapter, key)
26
- store.get(
27
- [
28
- adapter.class.to_s.split("::")[-1],
29
- key,
30
- ].join(":"),
31
- )
32
- end
33
-
34
- def record(adapter, key, milliseconds)
35
- compound_key = [
36
- adapter.class.to_s.split("::")[-1],
37
- key,
38
- ].join(":")
39
-
40
- # normalize timestamp
41
- milliseconds = [ milliseconds.round, 1 ].max
42
-
43
- store.record(compound_key, milliseconds)
44
- end
20
+ def enabled=(enabled)
21
+ unless [ true, false ].include?(enabled) || enabled.is_a?(Proc)
22
+ raise ArgumentError
23
+ end
45
24
 
46
- def timestamp
47
- Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1_000
25
+ @enabled = enabled
48
26
  end
49
27
 
50
- def time
51
- # if block_given?
52
- ts = -timestamp
53
- yield
28
+ def enable!
29
+ original = @enabled
30
+ @enabled = true
54
31
 
55
- ts += timestamp
32
+ yield if block_given?
33
+ ensure
34
+ @enabled = original if block_given?
56
35
  end
57
36
 
58
- def store
59
- @store ||= MemoryStore.new
60
- end
37
+ def disable!
38
+ original = @enabled
39
+ @enabled = false
61
40
 
62
- class Store
63
- def get(key)
64
- raise NotImplemented
65
- end
66
-
67
- def record(key, time)
68
- raise NotImplemented
69
- end
70
-
71
- def flush
72
- raise NotImplemented
73
- end
41
+ yield if block_given?
42
+ ensure
43
+ @enabled = original if block_given?
74
44
  end
75
45
 
76
- class MemoryStore < Store
77
- def initialize(substore = nil)
78
- @substore = substore
79
- @data = {}
80
- end
81
-
82
- def get(key)
83
- @data[key] ||= @substore&.get(key) || Stats.new
84
- end
85
-
86
- def record(key, time)
87
- get(key) << time
88
- @substore&.record(key, time)
89
-
90
- self
91
- end
92
-
93
- def flush
94
- @substore&.flush
95
- end
46
+ def timestamp
47
+ # milliseconds
48
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1_000
96
49
  end
97
50
 
98
- class RedisStore < Store
99
- def initialize(redis)
100
- @redis = redis
101
- end
102
-
103
- def cachekey(key)
104
- [ NetworkResiliency, key ].join(":")
105
- end
51
+ def reset
52
+ @enabled = nil
106
53
  end
107
54
  end
108
-
109
-
110
- require "network_resiliency/adapter/faraday"
111
- require "network_resiliency/adapter/redis"
112
-
113
- # ms granularity, round up, floor(1)
114
- #
115
-
116
- # storage
117
- # get(id) / record(id, time) / flush
118
-
119
- # local storage
120
- # - get(id) / save(id, time)
121
- # remote storage
122
- # - get(id) - sync
123
- # - save(id, time) - buffer and async flush
@@ -11,15 +11,16 @@ Gem::Specification.new do |s|
11
11
  s.summary = package.to_s
12
12
  s.version = package.const_get "VERSION"
13
13
 
14
- s.add_dependency "faraday"
14
+ s.required_ruby_version = ">= 3"
15
15
 
16
16
  s.add_development_dependency "byebug"
17
- s.add_development_dependency "codecov"
17
+ s.add_development_dependency "ddtrace", ">= 1"
18
+ s.add_development_dependency "dogstatsd-ruby", "<= 4.8.3"
19
+ s.add_development_dependency "faraday", "~> 1"
18
20
  s.add_development_dependency "faraday-rack"
19
21
  s.add_development_dependency "rack"
20
22
  s.add_development_dependency "rack-test"
21
- s.add_development_dependency "redis"
22
- s.add_development_dependency "redis-client", ">= 0.10"
23
+ s.add_development_dependency "redis", "~> 4"
23
24
  s.add_development_dependency "rspec"
24
25
  s.add_development_dependency "simplecov"
25
26
  end
metadata CHANGED
@@ -1,23 +1,23 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: network_resiliency
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.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-05-09 00:00:00.000000000 Z
11
+ date: 2023-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: faraday
14
+ name: byebug
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
- type: :runtime
20
+ type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
@@ -25,49 +25,49 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: byebug
28
+ name: ddtrace
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1'
41
41
  - !ruby/object:Gem::Dependency
42
- name: codecov
42
+ name: dogstatsd-ruby
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "<="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 4.8.3
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "<="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 4.8.3
55
55
  - !ruby/object:Gem::Dependency
56
- name: faraday-rack
56
+ name: faraday
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '1'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rack
70
+ name: faraday-rack
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rack-test
84
+ name: rack
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: redis
98
+ name: rack-test
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,19 +109,19 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: redis-client
112
+ name: redis
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.10'
117
+ version: '4'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0.10'
124
+ version: '4'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rspec
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -163,6 +163,7 @@ files:
163
163
  - README.md
164
164
  - lib/network_resiliency.rb
165
165
  - lib/network_resiliency/adapter/faraday.rb
166
+ - lib/network_resiliency/adapter/http.rb
166
167
  - lib/network_resiliency/adapter/redis.rb
167
168
  - lib/network_resiliency/stats.rb
168
169
  - lib/network_resiliency/version.rb
@@ -179,7 +180,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
179
180
  requirements:
180
181
  - - ">="
181
182
  - !ruby/object:Gem::Version
182
- version: '0'
183
+ version: '3'
183
184
  required_rubygems_version: !ruby/object:Gem::Requirement
184
185
  requirements:
185
186
  - - ">="