gruf-queue 0.1.2 → 0.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/README.md +8 -12
- data/lib/gruf/queue/plugin.rb +30 -69
- data/lib/gruf/queue/pool_enhancements.rb +3 -0
- data/lib/gruf/queue/queued_rpc_server.rb +2 -2
- data/lib/gruf/queue/version.rb +1 -1
- data/lib/gruf-queue.rb +1 -4
- metadata +1 -5
- data/lib/gruf/queue/configuration.rb +0 -64
- data/lib/gruf/queue/interceptors/connection_reset.rb +0 -87
- data/lib/gruf/queue/pool.rb +0 -89
- data/lib/gruf/queue/server_factory.rb +0 -99
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16b3387c40ed0f1175b3b6ee1127a15825788f17ae1ccd829385462d58c49913
|
4
|
+
data.tar.gz: d6694faf0538b2f6085a318433389ccf073c2f93876e78f1fb770bc061f6273d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b69971940855b247545a1488522d7b0abb9833c9d2eea4b4f8399e664fe9910f3a044a07e967e4cb3f8da91188b758d6ebdf5fd3097b477a51cf707d3275e13e
|
7
|
+
data.tar.gz: bc4d7414d8fdb9223721928facbb5b17db77bd753904a1419af72729ebaae22dcbcaf60244a53fca058ece126d9b1c16a284a3eb1ad0b7fbb92a1352a85d7591
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.1.3]
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
- **BREAKING**: Removed ServerFactory - use `QueuedRpcServer.new()` directly instead
|
12
|
+
- **BREAKING**: Removed Configuration wrapper - use Gruf's native configuration
|
13
|
+
- **BREAKING**: Removed custom ConnectionReset interceptor - use gruf's built-in `Gruf::Interceptors::ActiveRecord::ConnectionReset`
|
14
|
+
- Simplified plugin.rb from 104 to 60 lines by removing complex validation logic
|
15
|
+
- Merged pool.rb into pool_enhancements.rb for better organization
|
16
|
+
|
17
|
+
### Removed
|
18
|
+
- `Gruf::Queue::ServerFactory` - unnecessary abstraction layer
|
19
|
+
- `Gruf::Queue::Configuration` - wrapper around Gruf's native config
|
20
|
+
- `Gruf::Queue::Interceptors::ConnectionReset` - replaced with gruf's built-in
|
21
|
+
- `Gruf::Queue::Pool` class - functionality moved to PoolEnhancements module
|
22
|
+
- Obsolete test files and redundant test cases
|
23
|
+
|
24
|
+
### Improved
|
25
|
+
- **730 lines of code removed** - dramatically simplified codebase
|
26
|
+
- More direct and intuitive API without unnecessary abstractions
|
27
|
+
- Better integration with gruf's native features
|
28
|
+
- Cleaner test suite with eliminated logging noise
|
29
|
+
- Improved maintainability and reduced complexity
|
30
|
+
|
31
|
+
### Fixed
|
32
|
+
- Suppressed Gruf logger output during tests for cleaner test runs
|
33
|
+
- Updated all documentation and examples to reflect simplified API
|
34
|
+
|
8
35
|
## [0.1.2]
|
9
36
|
|
10
37
|
### Changed
|
data/README.md
CHANGED
@@ -84,7 +84,7 @@ Gruf.configure do |config|
|
|
84
84
|
config.rpc_server = Gruf::Queue::QueuedRpcServer
|
85
85
|
|
86
86
|
config.interceptors.use(
|
87
|
-
Gruf::
|
87
|
+
Gruf::Interceptors::ActiveRecord::ConnectionReset,
|
88
88
|
enabled: true,
|
89
89
|
target_classes: [ActiveRecord::Base]
|
90
90
|
)
|
@@ -108,19 +108,15 @@ Gruf.configure do |config|
|
|
108
108
|
end
|
109
109
|
```
|
110
110
|
|
111
|
-
###
|
111
|
+
### Custom Server Configuration
|
112
112
|
|
113
|
-
For
|
113
|
+
For custom server instances with specific options:
|
114
114
|
|
115
115
|
```ruby
|
116
|
-
# Create custom server instances
|
117
|
-
server = Gruf::Queue::
|
116
|
+
# Create custom server instances directly
|
117
|
+
server = Gruf::Queue::QueuedRpcServer.new(
|
118
118
|
pool_size: 15,
|
119
|
-
max_waiting_requests: 30
|
120
|
-
server: Gruf::Queue::QueuedRpcServer,
|
121
|
-
interceptors: [
|
122
|
-
Gruf::Queue::Interceptors::ConnectionReset
|
123
|
-
]
|
119
|
+
max_waiting_requests: 30
|
124
120
|
)
|
125
121
|
|
126
122
|
Gruf::Server.new(
|
@@ -139,7 +135,7 @@ The `ConnectionReset` interceptor automatically manages database connections:
|
|
139
135
|
# Customizable with additional target classes:
|
140
136
|
Gruf.configure do |config|
|
141
137
|
config.interceptors.use(
|
142
|
-
Gruf::
|
138
|
+
Gruf::Interceptors::ActiveRecord::ConnectionReset,
|
143
139
|
enabled: true,
|
144
140
|
target_classes: [ActiveRecord::Base, CustomConnectionClass]
|
145
141
|
)
|
@@ -162,7 +158,7 @@ Advanced thread pool implementation:
|
|
162
158
|
- Structured logging with thread identification
|
163
159
|
- Comprehensive error isolation and recovery
|
164
160
|
|
165
|
-
#### `Gruf::
|
161
|
+
#### `Gruf::Interceptors::ActiveRecord::ConnectionReset`
|
166
162
|
Smart database connection management:
|
167
163
|
- Automatically resets ActiveRecord connections after each request
|
168
164
|
- Validates connection handlers before attempting reset
|
data/lib/gruf/queue/plugin.rb
CHANGED
@@ -6,32 +6,18 @@ module Gruf
|
|
6
6
|
module Queue
|
7
7
|
# Plugin management for gruf-queue integration.
|
8
8
|
#
|
9
|
-
# Provides
|
10
|
-
# including RPC server setup and interceptor registration.
|
11
|
-
#
|
12
|
-
# @example Install plugin
|
13
|
-
# Gruf::Queue::Plugin.install! # => true
|
14
|
-
#
|
15
|
-
# @example Check installation status
|
16
|
-
# Gruf::Queue::Plugin.installed? # => true
|
9
|
+
# Provides simple installation and configuration of queue-specific settings.
|
17
10
|
class Plugin
|
18
11
|
class << self
|
19
12
|
def install!
|
20
13
|
return false if @installed
|
21
14
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
@installed = true
|
31
|
-
true
|
32
|
-
rescue StandardError
|
33
|
-
false
|
34
|
-
end
|
15
|
+
enhance_grpc_pool
|
16
|
+
configure_gruf
|
17
|
+
@installed = true
|
18
|
+
true
|
19
|
+
rescue StandardError
|
20
|
+
false
|
35
21
|
end
|
36
22
|
|
37
23
|
def installed?
|
@@ -40,63 +26,38 @@ module Gruf
|
|
40
26
|
|
41
27
|
def reset!
|
42
28
|
@installed = false
|
43
|
-
Configuration.reset! if Configuration.respond_to?(:reset!)
|
44
29
|
end
|
45
30
|
|
46
31
|
private
|
47
32
|
|
48
|
-
def configure_rpc_server(config)
|
49
|
-
config.rpc_server = QueuedRpcServer
|
50
|
-
end
|
51
|
-
|
52
|
-
def configure_interceptors(config)
|
53
|
-
return unless defined?(ActiveRecord)
|
54
|
-
|
55
|
-
validate_active_record_availability
|
56
|
-
ensure_interceptors_registry_available(config)
|
57
|
-
|
58
|
-
config.interceptors.use(
|
59
|
-
Interceptors::ConnectionReset,
|
60
|
-
enabled: true,
|
61
|
-
target_classes: [ActiveRecord::Base],
|
62
|
-
)
|
63
|
-
end
|
64
|
-
|
65
|
-
def validate_active_record_availability
|
66
|
-
return if ActiveRecord::Base.respond_to?(:connection_handler)
|
67
|
-
|
68
|
-
raise StandardError, 'ActiveRecord::Base does not support connection_handler'
|
69
|
-
end
|
70
|
-
|
71
|
-
def ensure_interceptors_registry_available(config)
|
72
|
-
return if config.respond_to?(:interceptors) && !config.interceptors.nil?
|
73
|
-
|
74
|
-
begin
|
75
|
-
require 'gruf/interceptors/registry'
|
76
|
-
rescue LoadError => e
|
77
|
-
raise StandardError, "Failed to load Gruf interceptors registry: #{e.message}"
|
78
|
-
end
|
79
|
-
|
80
|
-
if config.respond_to?(:interceptors=)
|
81
|
-
config.interceptors = ::Gruf::Interceptors::Registry.new
|
82
|
-
elsif config.respond_to?(:define_singleton_method)
|
83
|
-
registry = ::Gruf::Interceptors::Registry.new
|
84
|
-
config.define_singleton_method(:interceptors) { registry }
|
85
|
-
config.define_singleton_method(:interceptors=) { |val| registry = val }
|
86
|
-
else
|
87
|
-
raise StandardError, 'Cannot initialize interceptors registry: configuration object lacks required methods'
|
88
|
-
end
|
89
|
-
|
90
|
-
return if config.respond_to?(:interceptors) && config.interceptors.respond_to?(:use)
|
91
|
-
|
92
|
-
raise StandardError, 'Interceptors registry initialization failed: missing use method'
|
93
|
-
end
|
94
|
-
|
95
33
|
def enhance_grpc_pool
|
96
34
|
return if ::GRPC::Pool.included_modules.include?(Gruf::Queue::PoolEnhancements)
|
97
35
|
|
98
36
|
::GRPC::Pool.prepend(Gruf::Queue::PoolEnhancements)
|
99
37
|
end
|
38
|
+
|
39
|
+
def configure_gruf
|
40
|
+
Gruf.configure do |config|
|
41
|
+
# Set default server options compatible with QueuedRpcServer
|
42
|
+
config.rpc_server_options = {
|
43
|
+
pool_size: QueuedRpcServer::DEFAULT_POOL_SIZE,
|
44
|
+
max_waiting_requests: QueuedRpcServer::DEFAULT_MAX_WAITING_REQUESTS,
|
45
|
+
poll_period: QueuedRpcServer::DEFAULT_POLL_PERIOD,
|
46
|
+
pool_keep_alive: PoolEnhancements::DEFAULT_KEEP_ALIVE,
|
47
|
+
}
|
48
|
+
|
49
|
+
if defined?(ActiveRecord)
|
50
|
+
require 'gruf/interceptors/active_record/connection_reset'
|
51
|
+
# Configure interceptors at the global level
|
52
|
+
if Gruf.respond_to?(:interceptors)
|
53
|
+
Gruf.interceptors.use(
|
54
|
+
Gruf::Interceptors::ActiveRecord::ConnectionReset,
|
55
|
+
target_classes: [ActiveRecord::Base],
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
100
61
|
end
|
101
62
|
end
|
102
63
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'pool_enhancements'
|
4
4
|
|
5
5
|
module Gruf
|
6
6
|
module Queue
|
@@ -32,7 +32,7 @@ module Gruf
|
|
32
32
|
|
33
33
|
def initialize(pool_size: DEFAULT_POOL_SIZE,
|
34
34
|
max_waiting_requests: DEFAULT_MAX_WAITING_REQUESTS,
|
35
|
-
pool_keep_alive:
|
35
|
+
pool_keep_alive: PoolEnhancements::DEFAULT_KEEP_ALIVE,
|
36
36
|
poll_period: DEFAULT_POLL_PERIOD,
|
37
37
|
**args)
|
38
38
|
super
|
data/lib/gruf/queue/version.rb
CHANGED
data/lib/gruf-queue.rb
CHANGED
@@ -2,11 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'gruf'
|
4
4
|
require 'gruf/queue/version'
|
5
|
-
require 'gruf/queue/
|
5
|
+
require 'gruf/queue/pool_enhancements'
|
6
6
|
require 'gruf/queue/queued_rpc_server'
|
7
|
-
require 'gruf/queue/configuration'
|
8
|
-
require 'gruf/queue/server_factory'
|
9
|
-
require 'gruf/queue/interceptors/connection_reset'
|
10
7
|
require 'gruf/queue/plugin'
|
11
8
|
|
12
9
|
# Auto-install plugin when required unless explicitly disabled
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gruf-queue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ether Moon
|
@@ -135,13 +135,9 @@ files:
|
|
135
135
|
- README.md
|
136
136
|
- gruf-queue.gemspec
|
137
137
|
- lib/gruf-queue.rb
|
138
|
-
- lib/gruf/queue/configuration.rb
|
139
|
-
- lib/gruf/queue/interceptors/connection_reset.rb
|
140
138
|
- lib/gruf/queue/plugin.rb
|
141
|
-
- lib/gruf/queue/pool.rb
|
142
139
|
- lib/gruf/queue/pool_enhancements.rb
|
143
140
|
- lib/gruf/queue/queued_rpc_server.rb
|
144
|
-
- lib/gruf/queue/server_factory.rb
|
145
141
|
- lib/gruf/queue/version.rb
|
146
142
|
homepage: https://github.com/ether-moon/gruf-queue
|
147
143
|
licenses:
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gruf
|
4
|
-
module Queue
|
5
|
-
# Configuration management for gruf-queue integration.
|
6
|
-
#
|
7
|
-
# Enhances Gruf configuration with queue-specific settings and provides
|
8
|
-
# idempotent configuration setup with proper error handling.
|
9
|
-
#
|
10
|
-
# @example Configure Gruf
|
11
|
-
# Gruf::Queue::Configuration.configure
|
12
|
-
module Configuration
|
13
|
-
module_function
|
14
|
-
|
15
|
-
def configure
|
16
|
-
return if configured?
|
17
|
-
|
18
|
-
begin
|
19
|
-
Gruf.configure do |config|
|
20
|
-
enhance_gruf_configuration(config)
|
21
|
-
end
|
22
|
-
|
23
|
-
@configured = true
|
24
|
-
rescue StandardError => e
|
25
|
-
if defined?(Gruf) && Gruf.respond_to?(:logger)
|
26
|
-
Gruf.logger.error("Failed to enhance Gruf configuration: #{e.message}")
|
27
|
-
end
|
28
|
-
raise
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def configured?
|
33
|
-
!!@configured
|
34
|
-
end
|
35
|
-
|
36
|
-
def reset!
|
37
|
-
raise 'reset! can only be called in test environments' unless test_environment?
|
38
|
-
|
39
|
-
@configured = false
|
40
|
-
|
41
|
-
return unless defined?(Gruf) && Gruf.respond_to?(:configuration)
|
42
|
-
|
43
|
-
config = Gruf.configuration
|
44
|
-
config.rpc_server = nil if config.respond_to?(:rpc_server=)
|
45
|
-
end
|
46
|
-
|
47
|
-
def enhance_gruf_configuration(config)
|
48
|
-
config.define_singleton_method(:rpc_server) { @rpc_server }
|
49
|
-
config.define_singleton_method(:rpc_server=) { |val| @rpc_server = val }
|
50
|
-
config.rpc_server = nil unless config.respond_to?(:rpc_server)
|
51
|
-
|
52
|
-
return if Gruf.respond_to?(:configuration)
|
53
|
-
|
54
|
-
Gruf.define_singleton_method(:configuration) { config }
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_environment?
|
58
|
-
ENV['RACK_ENV'] == 'test' ||
|
59
|
-
ENV['RAILS_ENV'] == 'test' ||
|
60
|
-
defined?(RSpec)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gruf
|
4
|
-
module Queue
|
5
|
-
module Interceptors
|
6
|
-
# ActiveRecord connection reset interceptor for threaded gRPC environments.
|
7
|
-
#
|
8
|
-
# Automatically resets database connections after each request to prevent
|
9
|
-
# connection leaks and stale connections in multi-threaded environments.
|
10
|
-
#
|
11
|
-
# @example Basic usage with Gruf
|
12
|
-
# config.interceptors.use(
|
13
|
-
# Gruf::Queue::Interceptors::ConnectionReset,
|
14
|
-
# target_classes: [ActiveRecord::Base]
|
15
|
-
# )
|
16
|
-
class ConnectionReset < ::Gruf::Interceptors::ServerInterceptor
|
17
|
-
def initialize(request, call, method, options = {})
|
18
|
-
@request = request
|
19
|
-
@call = call
|
20
|
-
@method = method
|
21
|
-
@options = options || {}
|
22
|
-
@options[:enabled] = true unless @options.key?(:enabled)
|
23
|
-
end
|
24
|
-
|
25
|
-
def call
|
26
|
-
yield
|
27
|
-
ensure
|
28
|
-
begin
|
29
|
-
reset_connections if enabled?
|
30
|
-
rescue StandardError
|
31
|
-
# Ignore connection reset errors silently
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
attr_reader :options
|
38
|
-
|
39
|
-
def enabled?
|
40
|
-
return false if options[:enabled] == false
|
41
|
-
return false if target_classes.empty?
|
42
|
-
|
43
|
-
true
|
44
|
-
end
|
45
|
-
|
46
|
-
def reset_connections
|
47
|
-
validated_classes = validate_target_classes
|
48
|
-
return if validated_classes.empty?
|
49
|
-
|
50
|
-
validated_classes.each do |klass|
|
51
|
-
reset_connection_for_class(klass)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def target_classes
|
56
|
-
return Array(@target_classes).compact if instance_variable_defined?(:@target_classes)
|
57
|
-
|
58
|
-
default_classes = defined?(::ActiveRecord::Base) ? [::ActiveRecord::Base] : []
|
59
|
-
classes = options.fetch(:target_classes, default_classes)
|
60
|
-
Array(classes).compact
|
61
|
-
end
|
62
|
-
|
63
|
-
def validate_target_classes
|
64
|
-
target_classes.select do |klass|
|
65
|
-
valid_class?(klass)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def valid_class?(klass)
|
70
|
-
return false unless klass.is_a?(Class)
|
71
|
-
return false unless klass.respond_to?(:connection_handler)
|
72
|
-
|
73
|
-
true
|
74
|
-
end
|
75
|
-
|
76
|
-
def reset_connection_for_class(klass)
|
77
|
-
handler = klass.connection_handler
|
78
|
-
handler.clear_active_connections!(:all) if handler.respond_to?(:clear_active_connections!)
|
79
|
-
handler.clear_reloadable_connections! if handler.respond_to?(:clear_reloadable_connections!)
|
80
|
-
true
|
81
|
-
rescue StandardError
|
82
|
-
false
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
data/lib/gruf/queue/pool.rb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gruf
|
4
|
-
module Queue
|
5
|
-
# Enhanced thread pool with structured logging and improved error handling.
|
6
|
-
#
|
7
|
-
# Extends GRPC::Pool to provide better job scheduling, thread safety,
|
8
|
-
# and comprehensive error isolation for gRPC server request handling.
|
9
|
-
#
|
10
|
-
# @example Basic usage
|
11
|
-
# pool = Gruf::Queue::Pool.new(10, keep_alive: 300)
|
12
|
-
# pool.schedule { puts "Hello from worker thread" }
|
13
|
-
# pool.start
|
14
|
-
class Pool < ::GRPC::Pool
|
15
|
-
# Default keep-alive time for worker threads (in seconds)
|
16
|
-
DEFAULT_KEEP_ALIVE = 600
|
17
|
-
|
18
|
-
def initialize(size, keep_alive: DEFAULT_KEEP_ALIVE)
|
19
|
-
super
|
20
|
-
end
|
21
|
-
|
22
|
-
def jobs_waiting
|
23
|
-
@jobs&.size || 0
|
24
|
-
end
|
25
|
-
|
26
|
-
def schedule(*args, &blk)
|
27
|
-
return false if blk.nil?
|
28
|
-
|
29
|
-
@stop_mutex.synchronize do
|
30
|
-
return false if @stopped
|
31
|
-
|
32
|
-
@jobs << [blk, args]
|
33
|
-
true
|
34
|
-
end
|
35
|
-
rescue StandardError
|
36
|
-
false
|
37
|
-
end
|
38
|
-
|
39
|
-
def start
|
40
|
-
@stop_mutex.synchronize do
|
41
|
-
raise 'Pool already stopped' if @stopped
|
42
|
-
end
|
43
|
-
|
44
|
-
target_size = @size.to_i
|
45
|
-
|
46
|
-
until @workers.size == target_size
|
47
|
-
next_thread = create_worker_thread
|
48
|
-
@workers << next_thread if next_thread
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
protected
|
53
|
-
|
54
|
-
def create_worker_thread
|
55
|
-
Thread.new do
|
56
|
-
catch(:exit) do
|
57
|
-
_loop_execute_jobs
|
58
|
-
end
|
59
|
-
remove_current_thread
|
60
|
-
end
|
61
|
-
rescue StandardError
|
62
|
-
nil
|
63
|
-
end
|
64
|
-
|
65
|
-
def _loop_execute_jobs
|
66
|
-
Thread.current.name = "gruf-queue-worker-#{Thread.current.object_id}"
|
67
|
-
|
68
|
-
loop do
|
69
|
-
begin
|
70
|
-
blk, args = @jobs.pop
|
71
|
-
execute_job_safely(blk, args)
|
72
|
-
rescue ThreadError, SystemStackError, IOError
|
73
|
-
# Ignore system-level errors to prevent worker thread death
|
74
|
-
end
|
75
|
-
|
76
|
-
@stop_mutex.synchronize do
|
77
|
-
return if @stopped
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def execute_job_safely(blk, args)
|
83
|
-
blk.call(*args)
|
84
|
-
rescue SystemStackError, IOError, GRPC::Core::CallError, GRPC::BadStatus, Timeout::Error
|
85
|
-
# Ignore system/network/gRPC errors to prevent worker thread death
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gruf
|
4
|
-
module Queue
|
5
|
-
# Factory for creating configured gRPC servers with queue-specific options.
|
6
|
-
#
|
7
|
-
# Provides centralized server creation with intelligent defaults, option validation,
|
8
|
-
# and fallback handling for different server types.
|
9
|
-
#
|
10
|
-
# @example Create basic server
|
11
|
-
# server = Gruf::Queue::ServerFactory.create_server(pool_size: 20)
|
12
|
-
#
|
13
|
-
# @example Create with custom server class
|
14
|
-
# server = Gruf::Queue::ServerFactory.create_server(
|
15
|
-
# server: MyCustomServer,
|
16
|
-
# pool_size: 15
|
17
|
-
# )
|
18
|
-
module ServerFactory
|
19
|
-
module_function
|
20
|
-
|
21
|
-
# Create a new gRPC server instance with the provided options.
|
22
|
-
#
|
23
|
-
# @param opts [Hash] Configuration options for the server
|
24
|
-
# @option opts [Class] :server Custom server class to use
|
25
|
-
# @option opts [Integer] :pool_size Thread pool size
|
26
|
-
# @option opts [Proc] :event_listener_proc Event listener procedure
|
27
|
-
# @return [GRPC::RpcServer] Configured server instance
|
28
|
-
def create_server(opts = {})
|
29
|
-
# Default to QueuedRpcServer if no server specified
|
30
|
-
rpc_server = opts.fetch(:server, nil)
|
31
|
-
rpc_server ||= (defined?(Gruf) && Gruf.respond_to?(:rpc_server) && Gruf.rpc_server) || QueuedRpcServer
|
32
|
-
|
33
|
-
# Validate server class
|
34
|
-
validate_server_class!(rpc_server) if opts.key?(:server)
|
35
|
-
|
36
|
-
default_options = get_default_options
|
37
|
-
|
38
|
-
server_options = {
|
39
|
-
pool_size: opts.fetch(:pool_size, default_options[:pool_size]),
|
40
|
-
max_waiting_requests: opts.fetch(:max_waiting_requests, default_options[:max_waiting_requests]),
|
41
|
-
poll_period: opts.fetch(:poll_period, default_options[:poll_period]),
|
42
|
-
pool_keep_alive: opts.fetch(:pool_keep_alive, default_options[:pool_keep_alive]),
|
43
|
-
connect_md_proc: opts.fetch(:connect_md_proc, nil),
|
44
|
-
server_args: opts.fetch(:server_args, default_options[:server_args]),
|
45
|
-
}
|
46
|
-
|
47
|
-
# Handle interceptors via Gruf configuration if available
|
48
|
-
interceptors = opts.fetch(:interceptors, [])
|
49
|
-
if interceptors.any? && defined?(Gruf) && Gruf.respond_to?(:configuration)
|
50
|
-
interceptors.each do |interceptor|
|
51
|
-
Gruf.configuration.interceptors.use(interceptor, enabled: true)
|
52
|
-
end
|
53
|
-
elsif interceptors.any?
|
54
|
-
server_options[:interceptors] = interceptors
|
55
|
-
end
|
56
|
-
|
57
|
-
begin
|
58
|
-
rpc_server.new(**server_options)
|
59
|
-
rescue ArgumentError => e
|
60
|
-
raise unless e.message.include?('unknown keywords')
|
61
|
-
|
62
|
-
# Filter out unsupported options for basic GRPC::RpcServer
|
63
|
-
filtered_options = server_options.except(:pool_size, :max_waiting_requests, :poll_period, :pool_keep_alive)
|
64
|
-
rpc_server.new(**filtered_options)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Validate server class inherits from GRPC::RpcServer.
|
69
|
-
#
|
70
|
-
# @param server_class [Class] Server class to validate
|
71
|
-
# @raise [ArgumentError] if not a valid GRPC server class
|
72
|
-
# @return [void]
|
73
|
-
def validate_server_class!(server_class)
|
74
|
-
return if server_class.is_a?(Class) && server_class <= ::GRPC::RpcServer
|
75
|
-
|
76
|
-
raise ArgumentError, "Server must be a subclass of GRPC::RpcServer, got #{server_class}"
|
77
|
-
end
|
78
|
-
module_function :validate_server_class!
|
79
|
-
|
80
|
-
# Get default server options with Gruf integration fallback.
|
81
|
-
#
|
82
|
-
# @return [Hash] Default configuration options
|
83
|
-
def get_default_options
|
84
|
-
if defined?(Gruf) && Gruf.respond_to?(:rpc_server_options)
|
85
|
-
Gruf.rpc_server_options
|
86
|
-
else
|
87
|
-
{
|
88
|
-
pool_size: QueuedRpcServer::DEFAULT_POOL_SIZE,
|
89
|
-
max_waiting_requests: QueuedRpcServer::DEFAULT_MAX_WAITING_REQUESTS,
|
90
|
-
poll_period: QueuedRpcServer::DEFAULT_POLL_PERIOD,
|
91
|
-
pool_keep_alive: Pool::DEFAULT_KEEP_ALIVE,
|
92
|
-
server_args: {},
|
93
|
-
}
|
94
|
-
end
|
95
|
-
end
|
96
|
-
module_function :get_default_options
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|