fleck 2.2.1 → 2.2.3

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.
@@ -1,81 +1,81 @@
1
- # frozen_string_literal: true
2
-
3
- module Fleck
4
- module Core
5
- # Open `Consumer` class in order to define consumer helpers
6
- class Consumer
7
- # Define methods for 1xx codes
8
- information_method :continue!, 100
9
- information_method :switching_protocols!, 101
10
- information_method :processing!, 102
11
- information_method :early_hints!, 103
12
-
13
- # Define methods for 2xx codes
14
- success_method :ok!, 200
15
- success_method :created!, 201
16
- success_method :accepted!, 202
17
- success_method :non_authoritative_information!, 203
18
- success_method :no_content!, 204
19
- success_method :reset_content!, 205
20
- success_method :partial_content!, 206
21
- success_method :multi_status!, 207
22
- success_method :already_reported!, 208
23
- success_method :im_used!, 226
24
-
25
- # Define methods for 3xx codes
26
- redirect_method :multiple_choice!, 300
27
- redirect_method :moved_permanently!, 301
28
- redirect_method :found!, 302
29
- redirect_method :see_other!, 303
30
- redirect_method :not_modified!, 304
31
- redirect_method :use_proxy!, 305
32
- redirect_method :unused!, 306
33
- redirect_method :temporary_redirect!, 307
34
- redirect_method :permanent_redirect!, 308
35
-
36
- # Define methods for 4xx errors
37
- error_method :bad_request!, 400, 'Bad Request'
38
- error_method :unauthorized!, 401, 'Unauthorized'
39
- error_method :payment_required!, 402, 'Payment Required'
40
- error_method :forbidden!, 403, 'Forbidden'
41
- error_method :not_found!, 404, 'Not Found'
42
- error_method :method_not_allowed!, 405, 'Method Not Allowed'
43
- error_method :not_acceptable!, 406, 'Not Acceptable'
44
- error_method :proxy_authentication_required!, 407, 'Proxy Authentication Required'
45
- error_method :request_timeout!, 408, 'Request Timeout'
46
- error_method :conflict!, 409, 'Conflict'
47
- error_method :gone!, 410, 'Gone'
48
- error_method :length_required!, 411, 'Length Required'
49
- error_method :precondition_failed!, 412, 'Precondition Failed'
50
- error_method :payload_too_large!, 413, 'Payload Too Large'
51
- error_method :uri_too_long!, 414, 'URI Too Long'
52
- error_method :unsupported_media_type!, 415, 'Unsupported Media Type'
53
- error_method :range_not_satisfiable!, 416, 'Range Not Satisfiable'
54
- error_method :expectation_failed!, 417, 'Expectation Failed'
55
- error_method :im_a_teapot!, 418, "I'm a teapot"
56
- error_method :misdirected_request!, 421, 'Misdirected Request'
57
- error_method :unprocessable_entity!, 422, 'Unprocessable Entity'
58
- error_method :locked!, 423, 'Locked'
59
- error_method :failed_dependency!, 424, 'Failed Dependency'
60
- error_method :too_early!, 425, 'Too Early'
61
- error_method :upgrade_required!, 426, 'Upgrade Required'
62
- error_method :precondition_required!, 428, 'Precondition Required'
63
- error_method :too_many_requests!, 429, 'Too Many Requests'
64
- error_method :request_header_fields_too_large!, 431, 'Request Header Fields Too Large'
65
- error_method :unavailable_for_legal_reasons!, 451, 'Unavailable For Legal Reasons'
66
-
67
- # Define methods for 5xx errors
68
- error_method :internal_server_error!, 500, 'Internal Server Error'
69
- error_method :not_implemented!, 501, 'Not Implemented'
70
- error_method :bad_gateway!, 502, 'Bad Gateway'
71
- error_method :service_unavailable!, 503, 'Service Unavailable'
72
- error_method :gateway_timeout!, 504, 'Gateway Timeout'
73
- error_method :http_version_not_supported!, 505, 'HTTP Version Not Supported'
74
- error_method :variant_also_negotiates!, 506, 'Variant Also Negotiates'
75
- error_method :insufficient_storage!, 507, 'Insufficient Storage'
76
- error_method :loop_detected!, 508, 'Loop Detected'
77
- error_method :not_extended!, 510, 'Not Extended'
78
- error_method :network_authentication_required!, 511, 'Network Authentication Required'
79
- end
80
- end
81
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Fleck
4
+ module Core
5
+ # Open `Consumer` class in order to define consumer helpers
6
+ class Consumer
7
+ # Define methods for 1xx codes
8
+ information_method :continue!, 100
9
+ information_method :switching_protocols!, 101
10
+ information_method :processing!, 102
11
+ information_method :early_hints!, 103
12
+
13
+ # Define methods for 2xx codes
14
+ success_method :ok!, 200
15
+ success_method :created!, 201
16
+ success_method :accepted!, 202
17
+ success_method :non_authoritative_information!, 203
18
+ success_method :no_content!, 204
19
+ success_method :reset_content!, 205
20
+ success_method :partial_content!, 206
21
+ success_method :multi_status!, 207
22
+ success_method :already_reported!, 208
23
+ success_method :im_used!, 226
24
+
25
+ # Define methods for 3xx codes
26
+ redirect_method :multiple_choice!, 300
27
+ redirect_method :moved_permanently!, 301
28
+ redirect_method :found!, 302
29
+ redirect_method :see_other!, 303
30
+ redirect_method :not_modified!, 304
31
+ redirect_method :use_proxy!, 305
32
+ redirect_method :unused!, 306
33
+ redirect_method :temporary_redirect!, 307
34
+ redirect_method :permanent_redirect!, 308
35
+
36
+ # Define methods for 4xx errors
37
+ error_method :bad_request!, 400, 'Bad Request'
38
+ error_method :unauthorized!, 401, 'Unauthorized'
39
+ error_method :payment_required!, 402, 'Payment Required'
40
+ error_method :forbidden!, 403, 'Forbidden'
41
+ error_method :not_found!, 404, 'Not Found'
42
+ error_method :method_not_allowed!, 405, 'Method Not Allowed'
43
+ error_method :not_acceptable!, 406, 'Not Acceptable'
44
+ error_method :proxy_authentication_required!, 407, 'Proxy Authentication Required'
45
+ error_method :request_timeout!, 408, 'Request Timeout'
46
+ error_method :conflict!, 409, 'Conflict'
47
+ error_method :gone!, 410, 'Gone'
48
+ error_method :length_required!, 411, 'Length Required'
49
+ error_method :precondition_failed!, 412, 'Precondition Failed'
50
+ error_method :payload_too_large!, 413, 'Payload Too Large'
51
+ error_method :uri_too_long!, 414, 'URI Too Long'
52
+ error_method :unsupported_media_type!, 415, 'Unsupported Media Type'
53
+ error_method :range_not_satisfiable!, 416, 'Range Not Satisfiable'
54
+ error_method :expectation_failed!, 417, 'Expectation Failed'
55
+ error_method :im_a_teapot!, 418, "I'm a teapot"
56
+ error_method :misdirected_request!, 421, 'Misdirected Request'
57
+ error_method :unprocessable_entity!, 422, 'Unprocessable Entity'
58
+ error_method :locked!, 423, 'Locked'
59
+ error_method :failed_dependency!, 424, 'Failed Dependency'
60
+ error_method :too_early!, 425, 'Too Early'
61
+ error_method :upgrade_required!, 426, 'Upgrade Required'
62
+ error_method :precondition_required!, 428, 'Precondition Required'
63
+ error_method :too_many_requests!, 429, 'Too Many Requests'
64
+ error_method :request_header_fields_too_large!, 431, 'Request Header Fields Too Large'
65
+ error_method :unavailable_for_legal_reasons!, 451, 'Unavailable For Legal Reasons'
66
+
67
+ # Define methods for 5xx errors
68
+ error_method :internal_server_error!, 500, 'Internal Server Error'
69
+ error_method :not_implemented!, 501, 'Not Implemented'
70
+ error_method :bad_gateway!, 502, 'Bad Gateway'
71
+ error_method :service_unavailable!, 503, 'Service Unavailable'
72
+ error_method :gateway_timeout!, 504, 'Gateway Timeout'
73
+ error_method :http_version_not_supported!, 505, 'HTTP Version Not Supported'
74
+ error_method :variant_also_negotiates!, 506, 'Variant Also Negotiates'
75
+ error_method :insufficient_storage!, 507, 'Insufficient Storage'
76
+ error_method :loop_detected!, 508, 'Loop Detected'
77
+ error_method :not_extended!, 510, 'Not Extended'
78
+ error_method :network_authentication_required!, 511, 'Network Authentication Required'
79
+ end
80
+ end
81
+ end
@@ -124,7 +124,7 @@ module Fleck
124
124
  end
125
125
  rescue StandardError => e
126
126
  log_error(e)
127
- internal_server_error! e.inspect, interrupt: false
127
+ internal_server_error! error: e.inspect, interrupt: false
128
128
  ensure
129
129
  send_response!
130
130
  log_request
@@ -1,15 +1,15 @@
1
-
2
- module Fleck::Loggable
3
- def logger
4
- return @logger if @logger
5
-
6
- @logger = Fleck.logger.clone
7
- @logger.progname = self.class.name
8
-
9
- @logger
10
- end
11
-
12
- def log_error(error)
13
- logger.error "#{error.inspect}\n#{error.backtrace.join("\n")}"
14
- end
15
- end
1
+
2
+ module Fleck::Loggable
3
+ def logger
4
+ return @logger if @logger
5
+
6
+ @logger = Fleck.logger.clone
7
+ @logger.progname = self.class.name
8
+
9
+ @logger
10
+ end
11
+
12
+ def log_error(error)
13
+ logger.error "#{error.inspect}\n#{error.backtrace.join("\n")}"
14
+ end
15
+ end
@@ -1,102 +1,102 @@
1
- # frozen_string_literal: true
2
-
3
- require 'socket'
4
-
5
- # Open `Fleck` module to add `HostRating` class.
6
- module Fleck
7
- # `HostRating` class allows to test host latency on a regular basis and to compare the latency
8
- # with other hosts.
9
- class HostRating
10
- include Fleck::Loggable
11
-
12
- CONN_TIMEOUT = 5
13
-
14
- attr_reader :host, :port, :avg, :history
15
-
16
- def initialize(host: 'localhost', port: 5672, refresh_rate: 30_000, period: 300_000)
17
- @host = host
18
- @port = port
19
- @refresh_rate = refresh_rate
20
- @period = period
21
-
22
- # metrics
23
- @reachable = false
24
- @avg = 0
25
- @updated_at = nil
26
- @history = []
27
-
28
- refresh!
29
- @timer = Ztimer.every(@refresh_rate) { refresh! }
30
- end
31
-
32
- def reachable?
33
- @reachable
34
- end
35
-
36
- def close
37
- @timer.cancel!
38
- end
39
-
40
- def <=>(other)
41
- # the other host is reachable, so it comes first
42
- return 1 if !reachable? && other.reachable?
43
-
44
- # both host are unreachable, so they have the same priority
45
- return 0 unless reachable? || other.reachable?
46
-
47
- # the current host comes first, because it's reachable, while the other host is unreachable
48
- return -1 if reachable? && !other.reachable?
49
-
50
- # when both hosts are reachable, use avg latency to order them
51
- avg <=> other.avg
52
- end
53
-
54
- private
55
-
56
- def refresh!
57
- @history << measure_latency
58
- @history.shift if @history.size > @period / @refresh_rate
59
- @avg = @history.inject(:+).to_f / @history.size
60
- @reachable = true
61
- rescue SocketError, Timeout::Error => e
62
- @reachable = false
63
- logger.error "Connection error: #{@host}:#{@port} (#{e.inspect})"
64
- ensure
65
- @updated_at = Time.now
66
- end
67
-
68
- # Use a socket to test connection latency.
69
- def measure_latency
70
- socket = create_socket
71
-
72
- started_at = Time.now.to_f
73
- begin
74
- socket.connect_nonblock(sock_addr)
75
- rescue IO::WaitWritable
76
- IO.select(nil, [socket], nil, CONN_TIMEOUT) or raise Timeout::Error
77
- end
78
-
79
- (Time.now.to_f - started_at) * 1000 # ms
80
- ensure
81
- socket&.close
82
- end
83
-
84
- # Create a new socket for connection test.
85
- def create_socket
86
- socket = Socket.new(:AF_INET, :SOCK_STREAM, 0)
87
- socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
88
-
89
- socket
90
- end
91
-
92
- # Resolve domain name in order to obtain IP address to test.
93
- def sock_addr
94
- return @sock_addr if @sock_addr
95
-
96
- addr = Socket.getaddrinfo(@host, nil)
97
- @sock_addr = Socket.pack_sockaddr_in(@port, addr[0][3])
98
-
99
- @sock_addr
100
- end
101
- end
102
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'socket'
4
+
5
+ # Open `Fleck` module to add `HostRating` class.
6
+ module Fleck
7
+ # `HostRating` class allows to test host latency on a regular basis and to compare the latency
8
+ # with other hosts.
9
+ class HostRating
10
+ include Fleck::Loggable
11
+
12
+ CONN_TIMEOUT = 5
13
+
14
+ attr_reader :host, :port, :avg, :history
15
+
16
+ def initialize(host: 'localhost', port: 5672, refresh_rate: 30_000, period: 300_000)
17
+ @host = host
18
+ @port = port
19
+ @refresh_rate = refresh_rate
20
+ @period = period
21
+
22
+ # metrics
23
+ @reachable = false
24
+ @avg = 0
25
+ @updated_at = nil
26
+ @history = []
27
+
28
+ refresh!
29
+ @timer = Ztimer.every(@refresh_rate) { refresh! }
30
+ end
31
+
32
+ def reachable?
33
+ @reachable
34
+ end
35
+
36
+ def close
37
+ @timer.cancel!
38
+ end
39
+
40
+ def <=>(other)
41
+ # the other host is reachable, so it comes first
42
+ return 1 if !reachable? && other.reachable?
43
+
44
+ # both host are unreachable, so they have the same priority
45
+ return 0 unless reachable? || other.reachable?
46
+
47
+ # the current host comes first, because it's reachable, while the other host is unreachable
48
+ return -1 if reachable? && !other.reachable?
49
+
50
+ # when both hosts are reachable, use avg latency to order them
51
+ avg <=> other.avg
52
+ end
53
+
54
+ private
55
+
56
+ def refresh!
57
+ @history << measure_latency
58
+ @history.shift if @history.size > @period / @refresh_rate
59
+ @avg = @history.inject(:+).to_f / @history.size
60
+ @reachable = true
61
+ rescue SocketError, Timeout::Error => e
62
+ @reachable = false
63
+ logger.error "Connection error: #{@host}:#{@port} (#{e.inspect})"
64
+ ensure
65
+ @updated_at = Time.now
66
+ end
67
+
68
+ # Use a socket to test connection latency.
69
+ def measure_latency
70
+ socket = create_socket
71
+
72
+ started_at = Time.now.to_f
73
+ begin
74
+ socket.connect_nonblock(sock_addr)
75
+ rescue IO::WaitWritable
76
+ IO.select(nil, [socket], nil, CONN_TIMEOUT) or raise Timeout::Error
77
+ end
78
+
79
+ (Time.now.to_f - started_at) * 1000 # ms
80
+ ensure
81
+ socket&.close
82
+ end
83
+
84
+ # Create a new socket for connection test.
85
+ def create_socket
86
+ socket = Socket.new(:AF_INET, :SOCK_STREAM, 0)
87
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
88
+
89
+ socket
90
+ end
91
+
92
+ # Resolve domain name in order to obtain IP address to test.
93
+ def sock_addr
94
+ return @sock_addr if @sock_addr
95
+
96
+ addr = Socket.getaddrinfo(@host, nil)
97
+ @sock_addr = Socket.pack_sockaddr_in(@port, addr[0][3])
98
+
99
+ @sock_addr
100
+ end
101
+ end
102
+ end
data/lib/fleck/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Open `Fleck` module to set `VERSION` constant.
4
4
  module Fleck
5
- VERSION = '2.2.1'
5
+ VERSION = '2.2.3'
6
6
  end
data/lib/fleck.rb CHANGED
@@ -1,82 +1,82 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH << File.expand_path(__dir__)
4
-
5
- require 'English'
6
- require 'logger'
7
- require 'rainbow'
8
- require 'rainbow/ext/string'
9
- require 'bunny'
10
- require 'thread_safe'
11
- require 'securerandom'
12
- require 'oj'
13
- require 'ztimer'
14
- # require 'fleck/version'
15
- require 'fleck/utilities/hash_with_indifferent_access'
16
- # require 'fleck/loggable'
17
- # require 'fleck/host_rating'
18
- # require 'fleck/configuration'
19
- # require 'fleck/consumer'
20
- # require 'fleck/client'
21
-
22
- # `Fleck` module implements the features for `Fleck` configuration and messages production/consumption.
23
- module Fleck
24
- autoload :VERSION, 'fleck/version.rb'
25
- autoload :Loggable, 'fleck/loggable.rb'
26
- autoload :HostRating, 'fleck/utilities/host_rating.rb'
27
- autoload :Configuration, 'fleck/configuration.rb'
28
- autoload :Core, 'fleck/core.rb'
29
- autoload :Consumer, 'fleck/consumer.rb'
30
- autoload :Client, 'fleck/client.rb'
31
-
32
- @config = Configuration.new
33
- @consumers = ThreadSafe::Array.new
34
- @connections = ThreadSafe::Hash.new
35
-
36
- class << self
37
- attr_reader :config, :consumers
38
-
39
- def configure
40
- yield @config if block_given?
41
- @config
42
- end
43
-
44
- def logger
45
- @config.logger
46
- end
47
-
48
- def register_consumer(consumer_class)
49
- return if @consumers.include?(consumer_class)
50
-
51
- @consumers << consumer_class
52
- end
53
-
54
- def connection(options = {})
55
- opts = Fleck.config.default_options.merge(options)
56
- key = "ampq://#{opts[:user]}@#{opts[:host]}:#{opts[:port]}#{opts[:vhost]}"
57
- conn = @connections[key]
58
- if !conn || conn.closed?
59
- opts[:logger] = Fleck.logger.clone
60
- opts[:logger].progname += '::Bunny'
61
- logger.info "New connection #{key}"
62
- conn = Bunny.new(opts)
63
- conn.start
64
- @connections[key] = conn
65
- end
66
-
67
- conn
68
- end
69
-
70
- def terminate
71
- @connections.each do |key, connection|
72
- Fleck.logger.info "Closing connection #{key}"
73
- connection.close
74
- rescue StandardError => e
75
- Fleck.logger.error e.inspect
76
- end
77
- @connections.clear
78
-
79
- true
80
- end
81
- end
82
- end
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH << File.expand_path(__dir__)
4
+
5
+ require 'English'
6
+ require 'logger'
7
+ require 'rainbow'
8
+ require 'rainbow/ext/string'
9
+ require 'bunny'
10
+ require 'thread_safe'
11
+ require 'securerandom'
12
+ require 'oj'
13
+ require 'ztimer'
14
+ # require 'fleck/version'
15
+ require 'fleck/utilities/hash_with_indifferent_access'
16
+ # require 'fleck/loggable'
17
+ # require 'fleck/host_rating'
18
+ # require 'fleck/configuration'
19
+ # require 'fleck/consumer'
20
+ # require 'fleck/client'
21
+
22
+ # `Fleck` module implements the features for `Fleck` configuration and messages production/consumption.
23
+ module Fleck
24
+ autoload :VERSION, 'fleck/version.rb'
25
+ autoload :Loggable, 'fleck/loggable.rb'
26
+ autoload :HostRating, 'fleck/utilities/host_rating.rb'
27
+ autoload :Configuration, 'fleck/configuration.rb'
28
+ autoload :Core, 'fleck/core.rb'
29
+ autoload :Consumer, 'fleck/consumer.rb'
30
+ autoload :Client, 'fleck/client.rb'
31
+
32
+ @config = Configuration.new
33
+ @consumers = ThreadSafe::Array.new
34
+ @connections = ThreadSafe::Hash.new
35
+
36
+ class << self
37
+ attr_reader :config, :consumers
38
+
39
+ def configure
40
+ yield @config if block_given?
41
+ @config
42
+ end
43
+
44
+ def logger
45
+ @config.logger
46
+ end
47
+
48
+ def register_consumer(consumer_class)
49
+ return if @consumers.include?(consumer_class)
50
+
51
+ @consumers << consumer_class
52
+ end
53
+
54
+ def connection(options = {})
55
+ opts = Fleck.config.default_options.merge(options)
56
+ key = "ampq://#{opts[:user]}@#{opts[:host]}:#{opts[:port]}#{opts[:vhost]}"
57
+ conn = @connections[key]
58
+ if !conn || conn.closed?
59
+ opts[:logger] = Fleck.logger.clone
60
+ opts[:logger].progname += '::Bunny'
61
+ logger.info "New connection #{key}"
62
+ conn = Bunny.new(opts)
63
+ conn.start
64
+ @connections[key] = conn
65
+ end
66
+
67
+ conn
68
+ end
69
+
70
+ def terminate
71
+ @connections.each do |key, connection|
72
+ Fleck.logger.info "Closing connection #{key}"
73
+ connection.close
74
+ rescue StandardError => e
75
+ Fleck.logger.error e.inspect
76
+ end
77
+ @connections.clear
78
+
79
+ true
80
+ end
81
+ end
82
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fleck
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Groza Sergiu
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-04 00:00:00.000000000 Z
11
+ date: 2023-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler