semian 0.15.0 → 0.16.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: 9610bcda3bdfb95c885c6c31c4a2450a4c31824f877ad38e7ca3c34c4fd57d6c
4
- data.tar.gz: d748c2da29ba2ca844bc74354591196a6645a915d725fea07ab743d0b6343bf2
3
+ metadata.gz: 03aa7b6a715e0990279468f71a5bacbd03b94f983c16083570a09dc46c69d325
4
+ data.tar.gz: 1b53f85622bfa3868585ea8836df867a37da5b4142b769ad8b968d9865c001c2
5
5
  SHA512:
6
- metadata.gz: bf3e8a28916019f60f64ce668cd919e4b59e3ebcb50e397266363b7f43d093cbefd06bb41b9816351b9435484b5948eaf5c45e5408d677d76c0ac879ae98b21e
7
- data.tar.gz: b387b82d92712aba64d47e0a8ac33abc9789dba435e88e0020de6eae46881938fcdba5f16da39cbc3930e8a8e9b4bdacf3688388c9d328be25845915b341a5ce
6
+ metadata.gz: f7f481a7a77c6d91574500e2a636eb6bd9721e61be5c8740265f58ac90895525ed9b34750b7dbb23d97360a3449a7a990994d870c8a9730e8d06350afda7c7de
7
+ data.tar.gz: 216189dea6814080db529843164dd02235541127ce9058ff803cc3843842220e87340b45a73109a2004d6205194b166b0cbcbf55e46601a5bf5f00c75cb5678c
data/README.md CHANGED
@@ -211,7 +211,7 @@ calculate and adjust ticket counts.
211
211
 
212
212
  **Note**:
213
213
 
214
- - You must pass **exactly** one of ticket or quota.
214
+ - You must pass **exactly** one of options: `tickets` or `quota`.
215
215
  - Tickets available will be the ceiling of the quota ratio to the number of workers
216
216
  - So, with one worker, there will always be a minimum of 1 ticket
217
217
  - Workers in different processes will automatically unregister when the process exits.
@@ -236,7 +236,7 @@ SEMIAN_PARAMETERS = { tickets: 1,
236
236
  error_timeout: 10 }
237
237
  Semian::NetHTTP.semian_configuration = proc do |host, port|
238
238
  # Let's make it only active for github.com
239
- if host == "github.com" && port == "80"
239
+ if host == "github.com" && port.to_i == 80
240
240
  SEMIAN_PARAMETERS.merge(name: "github.com_80")
241
241
  else
242
242
  nil
@@ -282,19 +282,22 @@ Semian::NetHTTP.exceptions += [::OpenSSL::SSL::SSLError]
282
282
  Semian::NetHTTP.reset_exceptions
283
283
  # assert_equal(Semian::NetHTTP.exceptions, Semian::NetHTTP::DEFAULT_ERRORS)
284
284
  ```
285
+
285
286
  ##### Mark Unsuccessful Responses as Failures
286
- Unsuccessful responses (e.g. 5xx responses) do not raise exceptions, and as such are not marked as failures by default. The `open_circuit_server_errors` Semian configuration parameter may be set to enable this behaviour, to mark unsuccessful responses as failures as seen below:
287
+
288
+ Unsuccessful responses (e.g. 5xx responses) do not raise exceptions,
289
+ and as such are not marked as failures by default.
290
+ The `open_circuit_server_errors` Semian configuration parameter may be set to enable this behaviour,
291
+ to mark unsuccessful responses as failures as seen below:
287
292
 
288
293
  ```ruby
289
294
  SEMIAN_PARAMETERS = { tickets: 1,
290
295
  success_threshold: 1,
291
296
  error_threshold: 3,
292
297
  error_timeout: 10,
293
- open_circuit_server_errors: true}
298
+ open_circuit_server_errors: true }
294
299
  ```
295
300
 
296
-
297
-
298
301
  # Understanding Semian
299
302
 
300
303
  Semian is a library with heuristics for failing fast. This section will explain
@@ -415,7 +418,7 @@ response time. This is the problem Semian solves by failing fast.
415
418
 
416
419
  ## How does Semian work?
417
420
 
418
- Semian consists of two parts: circuit breaker and bulkheading. To understand
421
+ Semian consists of two parts: **Circuit breaker** and **Bulkheading**. To understand
419
422
  Semian, and especially how to configure it, we must understand these patterns
420
423
  and their implementation.
421
424
 
@@ -453,6 +456,8 @@ There are four configuration parameters for circuit breakers in Semian:
453
456
  * **error_threshold_timeout**. The amount of time in seconds that error_threshold errors must occur to open the circuit. Defaults to error_timeout seconds if not set.
454
457
  * **error_timeout**. The amount of time in seconds until trying to query the resource
455
458
  again.
459
+ * **error_threshold_timeout_enabled**. If set to false it will disable the time window for evicting old exceptions. `error_timeout` is still used and will reset
460
+ the circuit. Defaults to `true` if not set.
456
461
  * **success_threshold**. The amount of successes on the circuit until closing it
457
462
  again, that is to start accepting all requests to the circuit.
458
463
  * **half_open_resource_timeout**. Timeout for the resource in seconds when the circuit is half-open (supported for MySQL, Net::HTTP and Redis).
@@ -754,11 +759,13 @@ non-IO.
754
759
 
755
760
  # Developing Semian
756
761
 
757
- Semian requires a Linux environment. We provide a [docker-compose](https://docs.docker.com/compose/) file
758
- that runs MySQL, Redis, Toxiproxy and Ruby in containers. Use
759
- the steps below to work on Semian from a Mac OS environment.
762
+ Semian requires a Linux environment for **Bulkheading**.
763
+ We provide a [docker-compose](https://docs.docker.com/compose/) file
764
+ that runs MySQL, Redis, Toxiproxy and Ruby in containers.
765
+ Use the steps below to work on Semian from a Mac OS environment.
760
766
 
761
767
  ## Prerequisites :
768
+
762
769
  ```bash
763
770
  # install docker-for-desktop
764
771
  $ brew cask install docker
@@ -819,6 +826,17 @@ $ cd semian
819
826
  $ bundle exec rake test:parallel TEST_WORKERS=5 TEST_WORKER_NUM=1
820
827
  ```
821
828
 
829
+ ### Debug
830
+
831
+ Build a semian native extension with debug information.
832
+
833
+ ```shell
834
+ $ bundle exec rake clean --trace
835
+ $ export DEBUG=1
836
+ $ bundle exec rake build
837
+ $ bundle install
838
+ ```
839
+
822
840
  [hystrix]: https://github.com/Netflix/Hystrix
823
841
  [release-it]: https://pragprog.com/titles/mnee2/release-it-second-edition/
824
842
  [shopify]: http://www.shopify.com/
@@ -273,10 +273,10 @@ static void
273
273
  check_tickets_xor_quota_arg(VALUE tickets, VALUE quota)
274
274
  {
275
275
  if (tickets == Qnil && quota == Qnil) {
276
- rb_raise(rb_eArgError, "Semian configuration require either the :ticket or :quota parameter, you provided neither");
276
+ rb_raise(rb_eArgError, "Semian configuration require either the :tickets or :quota parameter, you provided neither");
277
277
  }
278
278
  if (tickets != Qnil && quota != Qnil) {
279
- rb_raise(rb_eArgError, "Semian configuration require either the :ticket or :quota parameter, you provided both");
279
+ rb_raise(rb_eArgError, "Semian configuration require either the :tickets or :quota parameter, you provided both");
280
280
  }
281
281
  }
282
282
 
@@ -10,6 +10,9 @@ and functions associated directly weth semops.
10
10
  #include <errno.h>
11
11
  #include <stdio.h>
12
12
  #include <string.h>
13
+ #ifdef DEBUG
14
+ #include <unistd.h>
15
+ #endif
13
16
 
14
17
  #include <openssl/sha.h>
15
18
  #include <ruby.h>
@@ -110,7 +113,8 @@ acquire_semaphore_without_gvl(void *p);
110
113
  static inline void
111
114
  print_sem_vals(int sem_id)
112
115
  {
113
- printf("lock %d, tickets: %d configured: %d, registered workers %d\n",
116
+ printf("[pid=%d][semian] semaphore values lock: %d, tickets: %d configured: %d, registered workers: %d\n",
117
+ getpid(),
114
118
  get_sem_val(sem_id, SI_SEM_LOCK),
115
119
  get_sem_val(sem_id, SI_SEM_TICKETS),
116
120
  get_sem_val(sem_id, SI_SEM_CONFIGURED_TICKETS),
@@ -6,16 +6,24 @@ module Semian
6
6
 
7
7
  def_delegators :@state, :closed?, :open?, :half_open?
8
8
 
9
- attr_reader :name, :half_open_resource_timeout, :error_timeout, :state, :last_error
9
+ attr_reader(
10
+ :name,
11
+ :half_open_resource_timeout,
12
+ :error_timeout,
13
+ :state,
14
+ :last_error,
15
+ :error_threshold_timeout_enabled,
16
+ )
10
17
 
11
18
  def initialize(name, exceptions:, success_threshold:, error_threshold:,
12
19
  error_timeout:, implementation:, half_open_resource_timeout: nil,
13
- error_threshold_timeout: nil)
20
+ error_threshold_timeout: nil, error_threshold_timeout_enabled: true)
14
21
 
15
22
  @name = name.to_sym
16
23
  @success_count_threshold = success_threshold
17
24
  @error_count_threshold = error_threshold
18
25
  @error_threshold_timeout = error_threshold_timeout || error_timeout
26
+ @error_threshold_timeout_enabled = error_threshold_timeout_enabled.nil? ? true : error_threshold_timeout_enabled
19
27
  @error_timeout = error_timeout
20
28
  @exceptions = exceptions
21
29
  @half_open_resource_timeout = half_open_resource_timeout
@@ -131,7 +139,10 @@ module Semian
131
139
  end
132
140
 
133
141
  def push_time(window, time: Time.now)
134
- window.reject! { |err_time| err_time + @error_threshold_timeout < time.to_i }
142
+ if error_threshold_timeout_enabled
143
+ window.reject! { |err_time| err_time + @error_threshold_timeout < time.to_i }
144
+ end
145
+
135
146
  window << time.to_i
136
147
  end
137
148
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Semian
4
- VERSION = "0.15.0"
4
+ VERSION = "0.16.0"
5
5
  end
data/lib/semian.rb CHANGED
@@ -276,6 +276,11 @@ module Semian
276
276
  error_threshold: options[:error_threshold],
277
277
  error_threshold_timeout: options[:error_threshold_timeout],
278
278
  error_timeout: options[:error_timeout],
279
+ error_threshold_timeout_enabled: if options[:error_threshold_timeout_enabled].nil?
280
+ true
281
+ else
282
+ options[:error_threshold_timeout_enabled]
283
+ end,
279
284
  exceptions: Array(exceptions) + [::Semian::BaseError],
280
285
  half_open_resource_timeout: options[:half_open_resource_timeout],
281
286
  implementation: implementation(**options),
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.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Francis
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-09-12 00:00:00.000000000 Z
13
+ date: 2022-10-05 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: |2
16
16
  A Ruby C extention that is used to control access to shared resources