kessel-sdk 1.12.0 → 1.13.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 +4 -4
- data/README.md +26 -0
- data/lib/kessel/inventory/GUIDELINES.md +19 -0
- data/lib/kessel/inventory.rb +51 -1
- data/lib/kessel/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a800ed3c85f59d9a3c3693b03a930d0c15c3f9469afcf7415439c1df6ce0ed5
|
|
4
|
+
data.tar.gz: 7af05d6be0c40cac48b26ce2a4e62168561b9b8291bbb320984676cc1a95385c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a2606225a968c861b8097c89f11076e111b48f2873cddcdce7784bb08e67c51df5cc7ef313686ebf4991c3d357323f8e35d751e68be2af27130aaa9faed99915
|
|
7
|
+
data.tar.gz: f9707c137cffaf0d86546da1986078baa60c887adde5e65835403e8fecd6f19ce3b781a9330c59455da3046e6cab80ef3163aea01b01cfad6e786657b5415689
|
data/README.md
CHANGED
|
@@ -130,6 +130,31 @@ client = KesselInventoryService::ClientBuilder.new(target)
|
|
|
130
130
|
|
|
131
131
|
Build the client **once at application startup and reuse it**. The underlying gRPC channel manages its own HTTP/2 connection pool.
|
|
132
132
|
|
|
133
|
+
### HTTP/2 Keepalive
|
|
134
|
+
|
|
135
|
+
All inventory clients now use these transport keepalive defaults, including clients created by existing builder chains:
|
|
136
|
+
|
|
137
|
+
- Ping interval: 45 seconds
|
|
138
|
+
- Ping acknowledgement timeout: 10 seconds
|
|
139
|
+
- Permit pings while there are no active calls: enabled
|
|
140
|
+
|
|
141
|
+
Override these values with the fluent `keepalive` method. Durations are finite positive real numbers in seconds and
|
|
142
|
+
are converted to integer milliseconds by truncating any fractional millisecond downward. The resulting value must be
|
|
143
|
+
between 1 and 2,147,483,647 milliseconds. Passing `nil` leaves that setting unchanged; `permit_without_calls` accepts
|
|
144
|
+
only `true` or `false` (including `false` as an explicit override).
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
client = Kessel::Inventory::V1beta2::KesselInventoryService::ClientBuilder
|
|
148
|
+
.new(ENV.fetch('KESSEL_ENDPOINT', nil))
|
|
149
|
+
.keepalive(interval: 60, timeout: 10, permit_without_calls: false)
|
|
150
|
+
.build
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The Ruby SDK sets `grpc.http2.max_pings_without_data` internally to avoid a local cap; it is not a public configuration
|
|
154
|
+
option. Before rollout, confirm that the Kessel server and any gateway enforce compatible keepalive policies
|
|
155
|
+
(RHCLOUD-51673). Keepalive is a transport-level ping mechanism, not an RPC health check and does not provide retries
|
|
156
|
+
or load-balancer guarantees. The builder still returns a gRPC stub; build it once and reuse it as usual.
|
|
157
|
+
|
|
133
158
|
### Check Permissions
|
|
134
159
|
|
|
135
160
|
```ruby
|
|
@@ -347,6 +372,7 @@ The `examples/` directory contains working examples. Set up environment variable
|
|
|
347
372
|
| `check_for_update_bulk.rb` | Bulk strongly consistent update checks |
|
|
348
373
|
| `delete_resource.rb` | Deleting resources |
|
|
349
374
|
| `fetch_workspaces.rb` | Fetching workspaces via RBAC HTTP API |
|
|
375
|
+
| `keepalive.rb` | Configuring HTTP/2 keepalive on an inventory client |
|
|
350
376
|
| `list_workspaces.rb` | Listing workspaces with auto-pagination |
|
|
351
377
|
| `report_resource.rb` | Reporting resource state |
|
|
352
378
|
| `console_principal.rb` | Building principals from `x-rh-identity` headers |
|
|
@@ -59,6 +59,25 @@ client = KesselInventoryService::ClientBuilder.new(target)
|
|
|
59
59
|
|
|
60
60
|
`build` returns a single gRPC stub instance (not a tuple). The underlying gRPC channel manages its own HTTP/2 connection pool. Build once at application startup and reuse -- do not create a new stub per request.
|
|
61
61
|
|
|
62
|
+
### HTTP/2 Keepalive
|
|
63
|
+
|
|
64
|
+
Every `ClientBuilder` passes these channel arguments to its service stub, including builders that do not call `keepalive`:
|
|
65
|
+
|
|
66
|
+
- `grpc.keepalive_time_ms`: 45,000 (45 seconds)
|
|
67
|
+
- `grpc.keepalive_timeout_ms`: 10,000 (10 seconds)
|
|
68
|
+
- `grpc.keepalive_permit_without_calls`: 1 (enabled)
|
|
69
|
+
- `grpc.http2.max_pings_without_data`: 0 (internal Ruby gRPC setting; not exposed as a public option)
|
|
70
|
+
|
|
71
|
+
`keepalive(interval: nil, timeout: nil, permit_without_calls: nil)` is fluent. Duration keywords are finite positive real
|
|
72
|
+
numbers in seconds, converted to integer milliseconds by truncating fractional milliseconds downward; the result must
|
|
73
|
+
be 1 through 2,147,483,647. `nil` leaves the existing setting unchanged, and `permit_without_calls` accepts only the
|
|
74
|
+
actual boolean values `true` and `false`. Each call validates every supplied value before changing any builder state.
|
|
75
|
+
|
|
76
|
+
These are transport ping settings, not RPC health checks, retries, or load-balancer guarantees. Check server and gateway
|
|
77
|
+
keepalive enforcement compatibility before rollout (RHCLOUD-51673); in particular, the 45-second interval may be
|
|
78
|
+
affected by an infrastructure-enforced minimum. Ruby's `grpc.http2.max_pings_without_data` value is internal and is not a
|
|
79
|
+
cross-SDK configuration knob.
|
|
80
|
+
|
|
62
81
|
## Service Wiring Pattern
|
|
63
82
|
|
|
64
83
|
Every gRPC service module must follow this exact pattern:
|
data/lib/kessel/inventory.rb
CHANGED
|
@@ -14,9 +14,24 @@ module Kessel
|
|
|
14
14
|
class ClientBuilder
|
|
15
15
|
include Kessel::GRPC
|
|
16
16
|
|
|
17
|
+
MAX_KEEPALIVE_MILLISECONDS = 2_147_483_647
|
|
18
|
+
private_constant :MAX_KEEPALIVE_MILLISECONDS
|
|
19
|
+
|
|
17
20
|
def initialize(target)
|
|
18
21
|
@target = target
|
|
19
22
|
raise 'Invalid target type' if @target.nil? || !@target.is_a?(String)
|
|
23
|
+
|
|
24
|
+
@channel_args = {
|
|
25
|
+
'grpc.keepalive_time_ms' => 45_000,
|
|
26
|
+
'grpc.keepalive_timeout_ms' => 10_000,
|
|
27
|
+
'grpc.keepalive_permit_without_calls' => 1,
|
|
28
|
+
'grpc.http2.max_pings_without_data' => 0
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def keepalive(interval: nil, timeout: nil, permit_without_calls: nil)
|
|
33
|
+
@channel_args.merge!(keepalive_channel_args(interval, timeout, permit_without_calls))
|
|
34
|
+
self
|
|
20
35
|
end
|
|
21
36
|
|
|
22
37
|
def oauth2_client_authenticated(oauth2_client_credentials:, channel_credentials: nil)
|
|
@@ -52,7 +67,7 @@ module Kessel
|
|
|
52
67
|
|
|
53
68
|
credentials = @channel_credentials
|
|
54
69
|
credentials = credentials.compose(@call_credentials) unless @call_credentials.nil?
|
|
55
|
-
self.class.stub_class.new(@target, credentials)
|
|
70
|
+
self.class.stub_class.new(@target, credentials, channel_args: @channel_args.dup)
|
|
56
71
|
end
|
|
57
72
|
|
|
58
73
|
private
|
|
@@ -66,6 +81,41 @@ module Kessel
|
|
|
66
81
|
|
|
67
82
|
raise 'Invalid credential configuration: can not authenticate with insecure channel'
|
|
68
83
|
end
|
|
84
|
+
|
|
85
|
+
def keepalive_channel_args(interval, timeout, permit_without_calls)
|
|
86
|
+
channel_args = {}
|
|
87
|
+
channel_args['grpc.keepalive_time_ms'] = duration_to_milliseconds(interval, 'interval') unless interval.nil?
|
|
88
|
+
channel_args['grpc.keepalive_timeout_ms'] = duration_to_milliseconds(timeout, 'timeout') unless timeout.nil?
|
|
89
|
+
|
|
90
|
+
unless permit_without_calls.nil?
|
|
91
|
+
unless permit_without_calls.equal?(true) || permit_without_calls.equal?(false)
|
|
92
|
+
raise 'Invalid keepalive permit_without_calls: must be true, false, or nil'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
channel_args['grpc.keepalive_permit_without_calls'] = permit_without_calls ? 1 : 0
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
channel_args
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def duration_to_milliseconds(value, name)
|
|
102
|
+
unless value.is_a?(Numeric) && !value.is_a?(Complex) && value.respond_to?(:finite?) && value.finite?
|
|
103
|
+
raise "Invalid keepalive #{name}: must be a finite real number of seconds"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
scaled_milliseconds = value * 1000
|
|
107
|
+
unless valid_scaled_keepalive_milliseconds?(scaled_milliseconds)
|
|
108
|
+
raise "Invalid keepalive #{name}: must convert to 1..#{MAX_KEEPALIVE_MILLISECONDS} milliseconds"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
scaled_milliseconds.floor
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def valid_scaled_keepalive_milliseconds?(milliseconds)
|
|
115
|
+
milliseconds.respond_to?(:finite?) &&
|
|
116
|
+
milliseconds.finite? &&
|
|
117
|
+
(1...(MAX_KEEPALIVE_MILLISECONDS + 1)).cover?(milliseconds)
|
|
118
|
+
end
|
|
69
119
|
end
|
|
70
120
|
end
|
|
71
121
|
end
|
data/lib/kessel/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kessel-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Project Kessel
|
|
@@ -314,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
314
314
|
- !ruby/object:Gem::Version
|
|
315
315
|
version: '0'
|
|
316
316
|
requirements: []
|
|
317
|
-
rubygems_version: 4.0.
|
|
317
|
+
rubygems_version: 4.0.22
|
|
318
318
|
specification_version: 4
|
|
319
319
|
summary: Ruby SDK for Project Kessel
|
|
320
320
|
test_files: []
|