consolle 0.2.6 → 0.2.8
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/.version +1 -1
- data/Gemfile +2 -2
- data/Gemfile.lock +1 -1
- data/bin/cone +2 -2
- data/bin/consolle +2 -2
- data/consolle.gemspec +20 -20
- data/lib/consolle/adapters/rails_console.rb +82 -77
- data/lib/consolle/cli.rb +380 -255
- data/lib/consolle/server/console_socket_server.rb +79 -72
- data/lib/consolle/server/console_supervisor.rb +216 -176
- data/lib/consolle/server/request_broker.rb +96 -99
- data/lib/consolle/version.rb +2 -2
- data/lib/consolle.rb +6 -6
- metadata +3 -3
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
3
|
+
require 'socket'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'logger'
|
|
6
|
+
require 'fileutils'
|
|
7
|
+
require_relative 'console_supervisor'
|
|
8
|
+
require_relative 'request_broker'
|
|
9
9
|
|
|
10
10
|
module Consolle
|
|
11
11
|
module Server
|
|
12
12
|
class ConsoleSocketServer
|
|
13
13
|
attr_reader :socket_path, :logger
|
|
14
14
|
|
|
15
|
-
def initialize(socket_path:, rails_root:, rails_env:
|
|
15
|
+
def initialize(socket_path:, rails_root:, rails_env: 'development', logger: nil, command: nil)
|
|
16
16
|
@socket_path = socket_path
|
|
17
17
|
@rails_root = rails_root
|
|
18
18
|
@rails_env = rails_env
|
|
19
|
-
@command = command ||
|
|
19
|
+
@command = command || 'bin/rails console'
|
|
20
20
|
@logger = logger || begin
|
|
21
21
|
log = Logger.new(STDOUT)
|
|
22
22
|
log.level = Logger::DEBUG
|
|
@@ -36,10 +36,10 @@ module Consolle
|
|
|
36
36
|
setup_supervisor
|
|
37
37
|
setup_broker
|
|
38
38
|
setup_signal_handlers
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
@running = true
|
|
41
41
|
@accept_thread = start_accept_loop
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
logger.info "[ConsoleSocketServer] Started at #{@socket_path}"
|
|
44
44
|
true
|
|
45
45
|
rescue StandardError => e
|
|
@@ -52,21 +52,25 @@ module Consolle
|
|
|
52
52
|
return false unless @running
|
|
53
53
|
|
|
54
54
|
@running = false
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
# Stop accepting new connections
|
|
57
|
-
|
|
57
|
+
begin
|
|
58
|
+
@server&.close
|
|
59
|
+
rescue StandardError
|
|
60
|
+
nil
|
|
61
|
+
end
|
|
58
62
|
@accept_thread&.join(5)
|
|
59
|
-
|
|
63
|
+
|
|
60
64
|
# Stop broker
|
|
61
65
|
@broker&.stop
|
|
62
|
-
|
|
66
|
+
|
|
63
67
|
# Stop supervisor
|
|
64
68
|
@supervisor&.stop
|
|
65
|
-
|
|
69
|
+
|
|
66
70
|
# Clean up socket file
|
|
67
71
|
File.unlink(@socket_path) if File.exist?(@socket_path)
|
|
68
|
-
|
|
69
|
-
logger.info
|
|
72
|
+
|
|
73
|
+
logger.info '[ConsoleSocketServer] Stopped'
|
|
70
74
|
true
|
|
71
75
|
end
|
|
72
76
|
|
|
@@ -80,15 +84,15 @@ module Consolle
|
|
|
80
84
|
# Ensure socket directory exists
|
|
81
85
|
socket_dir = File.dirname(@socket_path)
|
|
82
86
|
FileUtils.mkdir_p(socket_dir) unless Dir.exist?(socket_dir)
|
|
83
|
-
|
|
87
|
+
|
|
84
88
|
# Remove existing socket file
|
|
85
89
|
File.unlink(@socket_path) if File.exist?(@socket_path)
|
|
86
|
-
|
|
90
|
+
|
|
87
91
|
# Create Unix socket
|
|
88
92
|
@server = UNIXServer.new(@socket_path)
|
|
89
|
-
|
|
93
|
+
|
|
90
94
|
# Set permissions (owner only)
|
|
91
|
-
File.chmod(
|
|
95
|
+
File.chmod(0o600, @socket_path)
|
|
92
96
|
end
|
|
93
97
|
|
|
94
98
|
def setup_supervisor
|
|
@@ -127,6 +131,7 @@ module Consolle
|
|
|
127
131
|
rescue IOError => e
|
|
128
132
|
# Socket closed, expected during shutdown
|
|
129
133
|
break unless @running
|
|
134
|
+
|
|
130
135
|
logger.error "[ConsoleSocketServer] Accept error: #{e.message}"
|
|
131
136
|
rescue StandardError => e
|
|
132
137
|
logger.error "[ConsoleSocketServer] Unexpected error: #{e.message}"
|
|
@@ -138,57 +143,59 @@ module Consolle
|
|
|
138
143
|
|
|
139
144
|
def handle_client(client)
|
|
140
145
|
Thread.new do
|
|
146
|
+
# Read request
|
|
147
|
+
request_data = client.gets
|
|
148
|
+
return unless request_data
|
|
149
|
+
|
|
150
|
+
request = JSON.parse(request_data)
|
|
151
|
+
logger.debug "[ConsoleSocketServer] Request: #{request.inspect}"
|
|
152
|
+
|
|
153
|
+
# Process through broker
|
|
154
|
+
response = @broker.process_request(request)
|
|
155
|
+
|
|
156
|
+
# Send response
|
|
141
157
|
begin
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
logger.debug
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
client.write(JSON.generate(error_response))
|
|
185
|
-
client.write("\n")
|
|
186
|
-
rescue Errno::EPIPE
|
|
187
|
-
# Client disconnected while sending error response
|
|
188
|
-
logger.debug "[ConsoleSocketServer] Client disconnected while sending error response"
|
|
189
|
-
end
|
|
190
|
-
ensure
|
|
191
|
-
client.close rescue nil
|
|
158
|
+
client.write(JSON.generate(response))
|
|
159
|
+
client.write("\n")
|
|
160
|
+
client.flush
|
|
161
|
+
rescue Errno::EPIPE
|
|
162
|
+
# Client disconnected before we could send response
|
|
163
|
+
logger.debug '[ConsoleSocketServer] Client disconnected before response could be sent'
|
|
164
|
+
end
|
|
165
|
+
rescue JSON::ParserError => e
|
|
166
|
+
begin
|
|
167
|
+
error_response = {
|
|
168
|
+
'success' => false,
|
|
169
|
+
'error' => 'InvalidRequest',
|
|
170
|
+
'message' => "Invalid JSON: #{e.message}"
|
|
171
|
+
}
|
|
172
|
+
client.write(JSON.generate(error_response))
|
|
173
|
+
client.write("\n")
|
|
174
|
+
rescue Errno::EPIPE
|
|
175
|
+
logger.debug '[ConsoleSocketServer] Client disconnected while sending JSON parse error'
|
|
176
|
+
end
|
|
177
|
+
rescue Errno::EPIPE
|
|
178
|
+
# Client disconnected, ignore
|
|
179
|
+
logger.debug '[ConsoleSocketServer] Client disconnected (Broken pipe)'
|
|
180
|
+
rescue StandardError => e
|
|
181
|
+
logger.error "[ConsoleSocketServer] Client handler error: #{e.message}"
|
|
182
|
+
begin
|
|
183
|
+
error_response = {
|
|
184
|
+
'success' => false,
|
|
185
|
+
'error' => e.class.name,
|
|
186
|
+
'message' => e.message
|
|
187
|
+
}
|
|
188
|
+
client.write(JSON.generate(error_response))
|
|
189
|
+
client.write("\n")
|
|
190
|
+
rescue Errno::EPIPE
|
|
191
|
+
# Client disconnected while sending error response
|
|
192
|
+
logger.debug '[ConsoleSocketServer] Client disconnected while sending error response'
|
|
193
|
+
end
|
|
194
|
+
ensure
|
|
195
|
+
begin
|
|
196
|
+
client.close
|
|
197
|
+
rescue StandardError
|
|
198
|
+
nil
|
|
192
199
|
end
|
|
193
200
|
end
|
|
194
201
|
end
|
|
@@ -198,4 +205,4 @@ module Consolle
|
|
|
198
205
|
end
|
|
199
206
|
end
|
|
200
207
|
end
|
|
201
|
-
end
|
|
208
|
+
end
|