lex-node 0.3.5 → 0.3.6
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 +12 -0
- data/lib/legion/extensions/node/actors/cluster_control.rb +35 -0
- data/lib/legion/extensions/node/runners/node.rb +24 -0
- data/lib/legion/extensions/node/transport/exchanges/cluster_control.rb +17 -0
- data/lib/legion/extensions/node/transport/messages/cluster_killswitch.rb +45 -0
- data/lib/legion/extensions/node/transport/messages/cluster_settings.rb +43 -0
- data/lib/legion/extensions/node/transport/queues/cluster_control.rb +22 -0
- data/lib/legion/extensions/node/transport.rb +1 -0
- data/lib/legion/extensions/node/version.rb +1 -1
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc51c7fec2b526f23237c3c8da1c8457f7b10250ad7606a3d519049675025cc5
|
|
4
|
+
data.tar.gz: a0f8d664fdd16a3d16d64a948e3dfe2e8c27935251f1be5ffeef3bac21042220
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fd71f5b8d3152d625af005aef5add980d90548d6299bf7f6afd93b69585941b69c37b29ecc882d9325a0075d0fc60b744c9080305e2375350714f3a8cfcb52ba
|
|
7
|
+
data.tar.gz: c127f5a0b891e70df65b4639588a628596c8207ec31a21529bee8f39117c4cbf36b4d202d27b2619224e815035291bd8c8b81015f1a369071ff1041a8339d770
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.6] - 2026-03-31
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `legion.cluster.control` topic exchange for cluster-wide broadcast (durable, topic type)
|
|
7
|
+
- Per-node auto-delete queue `legion.cluster.control.<name>` bound to the exchange on boot
|
|
8
|
+
- `ClusterSettings` message: publishes settings changes with configurable routing key to the cluster control exchange
|
|
9
|
+
- `ClusterKillswitch` message: publishes emergency extension block via routing key `settings.extensions.blocked`
|
|
10
|
+
- `ClusterControl` subscription actor: subscribes to the per-node cluster control queue, routes to existing runners by routing key
|
|
11
|
+
- `Runners::Node#broadcast_settings(settings:, routing_key: 'settings', restart: false)`: sends settings to all nodes via the cluster control exchange
|
|
12
|
+
- `Runners::Node#killswitch(extension:)`: blocks an extension cluster-wide with immediate reload
|
|
13
|
+
- 51 new specs covering all new components (162 total, 0 failures)
|
|
14
|
+
|
|
3
15
|
## [0.3.5] - 2026-03-30
|
|
4
16
|
|
|
5
17
|
### Changed
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Node
|
|
6
|
+
module Actor
|
|
7
|
+
class ClusterControl < Legion::Extensions::Actors::Subscription
|
|
8
|
+
def runner_class
|
|
9
|
+
Legion::Extensions::Node::Runners::Node
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def queue_class
|
|
13
|
+
Legion::Extensions::Node::Transport::Queues::ClusterControl
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def disabled?
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def use_runner?
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def check_subtask?
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def generate_task?
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -120,6 +120,30 @@ module Legion
|
|
|
120
120
|
public_key: public_key)
|
|
121
121
|
end
|
|
122
122
|
|
|
123
|
+
def broadcast_settings(settings:, routing_key: 'settings', restart: false, **_opts)
|
|
124
|
+
log.debug "broadcast_settings: routing_key=#{routing_key} keys=#{settings.keys.join(', ')}"
|
|
125
|
+
Legion::Extensions::Node::Transport::Messages::ClusterSettings.new(
|
|
126
|
+
settings: settings,
|
|
127
|
+
routing_key: routing_key,
|
|
128
|
+
restart: restart
|
|
129
|
+
).publish
|
|
130
|
+
{}
|
|
131
|
+
rescue StandardError => e
|
|
132
|
+
log.error "broadcast_settings failed: #{e.message}"
|
|
133
|
+
{}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def killswitch(extension:, **_opts)
|
|
137
|
+
log.debug "killswitch: blocking extension #{extension} cluster-wide"
|
|
138
|
+
Legion::Extensions::Node::Transport::Messages::ClusterKillswitch.new(
|
|
139
|
+
extension: extension.to_s.delete_prefix('lex-')
|
|
140
|
+
).publish
|
|
141
|
+
{}
|
|
142
|
+
rescue StandardError => e
|
|
143
|
+
log.error "killswitch failed: #{e.message}"
|
|
144
|
+
{}
|
|
145
|
+
end
|
|
146
|
+
|
|
123
147
|
private
|
|
124
148
|
|
|
125
149
|
def publish_update_result(action:, status:, detail: nil, error: nil)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Node
|
|
6
|
+
module Transport
|
|
7
|
+
module Exchanges
|
|
8
|
+
class ClusterControl
|
|
9
|
+
EXCHANGE_NAME = 'legion.cluster.control'
|
|
10
|
+
EXCHANGE_TYPE = :topic
|
|
11
|
+
EXCHANGE_OPTIONS = { durable: true }.freeze
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Node
|
|
6
|
+
module Transport
|
|
7
|
+
module Messages
|
|
8
|
+
class ClusterKillswitch < Legion::Transport::Message
|
|
9
|
+
ROUTING_KEY = 'settings.extensions.blocked'
|
|
10
|
+
|
|
11
|
+
def routing_key
|
|
12
|
+
ROUTING_KEY
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def exchange
|
|
16
|
+
Legion::Extensions::Node::Transport::Exchanges::ClusterControl
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def type
|
|
20
|
+
'task'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def encrypt?
|
|
24
|
+
false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def message
|
|
28
|
+
{
|
|
29
|
+
function: 'update_settings',
|
|
30
|
+
settings: { extensions: { blocked: [@options[:extension]] } },
|
|
31
|
+
restart: true
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def validate
|
|
36
|
+
raise 'extension must be a String' unless @options[:extension].is_a?(String)
|
|
37
|
+
|
|
38
|
+
@valid = true
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Node
|
|
6
|
+
module Transport
|
|
7
|
+
module Messages
|
|
8
|
+
class ClusterSettings < Legion::Transport::Message
|
|
9
|
+
def routing_key
|
|
10
|
+
@options.fetch(:routing_key, 'settings')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def exchange
|
|
14
|
+
Legion::Extensions::Node::Transport::Exchanges::ClusterControl
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def type
|
|
18
|
+
'task'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def encrypt?
|
|
22
|
+
false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def message
|
|
26
|
+
{
|
|
27
|
+
function: 'update_settings',
|
|
28
|
+
settings: @options[:settings],
|
|
29
|
+
restart: @options.fetch(:restart, false)
|
|
30
|
+
}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def validate
|
|
34
|
+
raise 'settings must be a Hash' unless @options[:settings].is_a?(Hash)
|
|
35
|
+
|
|
36
|
+
@valid = true
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Node
|
|
6
|
+
module Transport
|
|
7
|
+
module Queues
|
|
8
|
+
class ClusterControl < Legion::Transport::Queue
|
|
9
|
+
def queue_name
|
|
10
|
+
"legion.cluster.control.#{Legion::Settings[:client][:name]}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def queue_options
|
|
14
|
+
{ durable: false, exclusive: false, auto_delete: true,
|
|
15
|
+
arguments: { 'x-queue-type': 'classic' } }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -13,6 +13,7 @@ module Legion
|
|
|
13
13
|
array.push(from: 'node', to: 'node', routing_key: 'node.data.#') if Legion::Settings[:data]&.[](:connected) || false
|
|
14
14
|
array.push(from: 'node', to: 'node', routing_key: 'node.cache.#') if Legion::Settings[:cache]&.[](:connected) || false
|
|
15
15
|
array.push(from: 'node', to: 'node', routing_key: 'node.crypt.#')
|
|
16
|
+
array.push(from: 'cluster_control', to: 'cluster_control', routing_key: '#')
|
|
16
17
|
array
|
|
17
18
|
end
|
|
18
19
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-node
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -145,6 +145,7 @@ files:
|
|
|
145
145
|
- lex-node.gemspec
|
|
146
146
|
- lib/legion/extensions/node.rb
|
|
147
147
|
- lib/legion/extensions/node/actors/beat.rb
|
|
148
|
+
- lib/legion/extensions/node/actors/cluster_control.rb
|
|
148
149
|
- lib/legion/extensions/node/actors/crypt.rb
|
|
149
150
|
- lib/legion/extensions/node/actors/push_key.rb
|
|
150
151
|
- lib/legion/extensions/node/actors/vault.rb
|
|
@@ -160,8 +161,11 @@ files:
|
|
|
160
161
|
- lib/legion/extensions/node/runners/node.rb
|
|
161
162
|
- lib/legion/extensions/node/runners/vault.rb
|
|
162
163
|
- lib/legion/extensions/node/transport.rb
|
|
164
|
+
- lib/legion/extensions/node/transport/exchanges/cluster_control.rb
|
|
163
165
|
- lib/legion/extensions/node/transport/exchanges/node.rb
|
|
164
166
|
- lib/legion/extensions/node/transport/messages/beat.rb
|
|
167
|
+
- lib/legion/extensions/node/transport/messages/cluster_killswitch.rb
|
|
168
|
+
- lib/legion/extensions/node/transport/messages/cluster_settings.rb
|
|
165
169
|
- lib/legion/extensions/node/transport/messages/public_key.rb
|
|
166
170
|
- lib/legion/extensions/node/transport/messages/push_cluster_secret.rb
|
|
167
171
|
- lib/legion/extensions/node/transport/messages/push_vault_token.rb
|
|
@@ -169,6 +173,7 @@ files:
|
|
|
169
173
|
- lib/legion/extensions/node/transport/messages/request_public_keys.rb
|
|
170
174
|
- lib/legion/extensions/node/transport/messages/request_vault_token.rb
|
|
171
175
|
- lib/legion/extensions/node/transport/messages/update_result.rb
|
|
176
|
+
- lib/legion/extensions/node/transport/queues/cluster_control.rb
|
|
172
177
|
- lib/legion/extensions/node/transport/queues/crypt.rb
|
|
173
178
|
- lib/legion/extensions/node/transport/queues/health.rb
|
|
174
179
|
- lib/legion/extensions/node/transport/queues/node.rb
|