kafkr 0.13.0 → 0.018.1
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/exe/kafkr +4 -4
- data/exe/kafkr-consumer +5 -6
- data/exe/kafkr-keys +1 -1
- data/exe/kafkr-producer +5 -5
- data/handlers/web_handler.rb +0 -1
- data/lib/kafkr/consumer.rb +14 -16
- data/lib/kafkr/encryptor.rb +2 -2
- data/lib/kafkr/log.rb +23 -21
- data/lib/kafkr/message_broker.rb +9 -7
- data/lib/kafkr/producer.rb +7 -5
- data/lib/kafkr/version.rb +1 -1
- data/lib/kafkr.rb +1 -10
- 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: 1e7fd62a57849b5096b9cba1a6928ee2786a401084ca29af0bfdfb1fc2cab7c5
|
4
|
+
data.tar.gz: 6ca89348304182eeabb6c4518818ad804d6b1b4c429c52ba82905cbf431bbb12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2ec64c8b63a6b57860ad372ca2dc851dffca1955f7ffe0a1958aaa3a636e50f05fd581e5556761355c8515317c16f29b4d78c8d839c7c429976789d2fcfcb61
|
7
|
+
data.tar.gz: f10c003cecfacbcd05376832784430262bcdb26244efe5c345a22bdf30a75ca67b335e48bc1a6b6c72476619ab984c3b4d66a10b54562b5805940ee4e9974b9a
|
data/exe/kafkr
CHANGED
@@ -6,19 +6,19 @@ PORT = ENV["KAFKR_PORT"] || 4000
|
|
6
6
|
begin
|
7
7
|
require "kafkr"
|
8
8
|
rescue LoadError => e
|
9
|
-
|
9
|
+
Kafkr.log "Failed to load Kafkr: #{e.message}"
|
10
10
|
exit(1)
|
11
11
|
end
|
12
12
|
|
13
13
|
begin
|
14
14
|
server = Kafkr::Log.new(PORT.to_i)
|
15
|
-
|
15
|
+
Kafkr.log "Kafkr Log version #{Kafkr::VERSION} started on port #{PORT}!"
|
16
16
|
server.start
|
17
17
|
rescue => e
|
18
|
-
|
18
|
+
Kafkr.log "An error occurred: #{e.message}"
|
19
19
|
exit(1)
|
20
20
|
rescue Interrupt
|
21
|
-
|
21
|
+
Kafkr.log "\nLog server shutting down gracefully..."
|
22
22
|
server.stop if server.respond_to?(:stop)
|
23
23
|
exit(0)
|
24
24
|
end
|
data/exe/kafkr-consumer
CHANGED
@@ -7,9 +7,9 @@ require "digest"
|
|
7
7
|
# Accepting command line arguments for host and port
|
8
8
|
host = ARGV[0] || "localhost"
|
9
9
|
port = ARGV[1] || 4000
|
10
|
-
timeout = ARGV[2] ||
|
10
|
+
timeout = ARGV[2] || 300
|
11
11
|
|
12
|
-
|
12
|
+
Kafkr.log "Running on host: #{host} and port: #{port}"
|
13
13
|
|
14
14
|
$current_consumer = nil
|
15
15
|
$restart_required = false
|
@@ -26,16 +26,15 @@ def stop_consumer
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def list_registered_handlers
|
29
|
-
puts "Registered Handlers:"
|
30
29
|
Kafkr::Consumer.handlers.each do |handler|
|
31
30
|
$loaded_handlers = {}
|
32
31
|
handler_name = handler.class.name.split("::").last.gsub(/Handler$/, "")
|
33
|
-
|
32
|
+
Kafkr.log "#{handler_name} handler registered."
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
36
|
def start_consumer(port, host, timeout)
|
38
|
-
|
37
|
+
Kafkr.log "Starting consumer on port #{port}! timeout: #{timeout}"
|
39
38
|
$handlers_changed = false
|
40
39
|
|
41
40
|
Kafkr::Consumer.configure do |config|
|
@@ -69,7 +68,7 @@ def reload_handlers(file_checksums)
|
|
69
68
|
if new_handlers.any?
|
70
69
|
new_handlers.each do |handler|
|
71
70
|
handler_name = handler.class.name.split("::").last.gsub(/Handler$/, "").capitalize
|
72
|
-
|
71
|
+
Kafkr.log "#{handler_name} handler updated - ok!"
|
73
72
|
end
|
74
73
|
end
|
75
74
|
end
|
data/exe/kafkr-keys
CHANGED
data/exe/kafkr-producer
CHANGED
@@ -5,12 +5,12 @@ require "readline"
|
|
5
5
|
host = ARGV[0] || "localhost"
|
6
6
|
port = ARGV[1] || 4000
|
7
7
|
|
8
|
-
|
8
|
+
kakf "Running on host: #{host} and port: #{port}"
|
9
9
|
|
10
10
|
begin
|
11
11
|
require "kafkr"
|
12
12
|
rescue LoadError => e
|
13
|
-
|
13
|
+
Kafkr.log "Failed to load Kafkr: #{e.message}"
|
14
14
|
exit(1)
|
15
15
|
end
|
16
16
|
|
@@ -24,15 +24,15 @@ begin
|
|
24
24
|
break if line == "exit"
|
25
25
|
|
26
26
|
if line.include? "<=>"
|
27
|
-
|
27
|
+
Kafkr.log Kafkr::Producer.send_message_and_wait(line)
|
28
28
|
else
|
29
29
|
Kafkr::Producer.send_message(line)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
rescue => e
|
33
|
-
|
33
|
+
Kafkr.log "An error occurred: #{e.message}"
|
34
34
|
exit(1)
|
35
35
|
rescue Interrupt
|
36
|
-
|
36
|
+
Kafkr.log "\nProducer server shutting down gracefully..."
|
37
37
|
exit(0)
|
38
38
|
end
|
data/handlers/web_handler.rb
CHANGED
data/lib/kafkr/consumer.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "socket"
|
1
|
+
require "socket"
|
2
2
|
require "timeout"
|
3
3
|
require "ostruct"
|
4
4
|
require "fileutils"
|
@@ -19,8 +19,8 @@ module Kafkr
|
|
19
19
|
FileUtils.mkdir_p "./.kafkr"
|
20
20
|
@configuration ||= OpenStruct.new
|
21
21
|
@configuration.host = ENV.fetch("KAFKR_HOST", "localhost")
|
22
|
-
@configuration.port = ENV.fetch("KAFKR_PORT",
|
23
|
-
@configuration.timeout = ENV.fetch("KAFKR_CONSUMER_TIMEOUT",
|
22
|
+
@configuration.port = ENV.fetch("KAFKR_PORT", 4000)
|
23
|
+
@configuration.timeout = ENV.fetch("KAFKR_CONSUMER_TIMEOUT", 300)
|
24
24
|
@configuration.suggest_handlers = false
|
25
25
|
@configuration
|
26
26
|
end
|
@@ -37,8 +37,8 @@ module Kafkr
|
|
37
37
|
$handlers_changed = true
|
38
38
|
|
39
39
|
def list_registered_handlers
|
40
|
-
|
41
|
-
$loaded_handlers.keys.each { |handler|
|
40
|
+
Kafkr.log "Registered handlers:"
|
41
|
+
$loaded_handlers.keys.each { |handler| Kafkr.log "- #{handler}" }
|
42
42
|
end
|
43
43
|
|
44
44
|
def load_handlers(directory = "./handlers")
|
@@ -124,7 +124,7 @@ module Kafkr
|
|
124
124
|
|
125
125
|
if Kafkr::Consumer.configuration.suggest_handlers
|
126
126
|
if valid_class_name?(name.capitalize)
|
127
|
-
|
127
|
+
Kafkr.log "No handler for this message, you could use this one.\n\n"
|
128
128
|
|
129
129
|
handler_class_string = <<~HANDLER_CLASS
|
130
130
|
class #{name.capitalize}Handler < Kafkr::Consumer::Handler
|
@@ -133,14 +133,14 @@ module Kafkr
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def handle(message)
|
136
|
-
|
136
|
+
Kafkr.log message
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
140
|
# Save the file to ./handlers/#{name}_handler.rb
|
141
141
|
HANDLER_CLASS
|
142
142
|
|
143
|
-
|
143
|
+
Kafkr.log handler_class_string
|
144
144
|
end
|
145
145
|
end
|
146
146
|
end
|
@@ -160,20 +160,17 @@ module Kafkr
|
|
160
160
|
received_message = socket.gets
|
161
161
|
raise LostConnection if received_message.nil?
|
162
162
|
received_message = Kafkr::Encryptor.new.decrypt(received_message.chomp)
|
163
|
-
if
|
164
|
-
|
165
|
-
return payload if payload
|
166
|
-
end
|
163
|
+
payload = yield received_message, sync_uid if block_given?
|
164
|
+
return payload
|
167
165
|
end
|
168
166
|
end
|
169
167
|
rescue Timeout::Error, LostConnection, Errno::ECONNREFUSED
|
170
168
|
attempt += 1
|
171
169
|
wait_time = backoff_time(attempt)
|
172
|
-
puts "Attempt #{attempt}: Retrying in #{wait_time} seconds..."
|
173
170
|
sleep(wait_time)
|
174
171
|
retry
|
175
172
|
rescue Interrupt
|
176
|
-
|
173
|
+
Kafkr.log "Received interrupt signal. Shutting down consumer gracefully..."
|
177
174
|
socket&.close
|
178
175
|
exit(0)
|
179
176
|
end
|
@@ -182,8 +179,9 @@ module Kafkr
|
|
182
179
|
def listen
|
183
180
|
attempt = 0
|
184
181
|
loop do
|
185
|
-
listen_for("dummy", ->(msg) {
|
186
|
-
|
182
|
+
listen_for("dummy", ->(msg) { }) do |message|
|
183
|
+
Kafkr.log ">> #{message}"
|
184
|
+
dispatch_to_handlers(message)
|
187
185
|
end
|
188
186
|
end
|
189
187
|
end
|
data/lib/kafkr/encryptor.rb
CHANGED
@@ -19,7 +19,7 @@ module Kafkr
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def decrypt(encrypted_data)
|
22
|
-
#
|
22
|
+
# Kafkr.log "Encrypted data before decoding: #{encrypted_data.inspect}"
|
23
23
|
decipher = OpenSSL::Cipher.new(ALGORITHM)
|
24
24
|
decipher.decrypt
|
25
25
|
decipher.key = @key
|
@@ -27,7 +27,7 @@ module Kafkr
|
|
27
27
|
decipher.iv = raw_data[0, decipher.iv_len]
|
28
28
|
decipher.update(raw_data[decipher.iv_len..-1]) + decipher.final
|
29
29
|
rescue OpenSSL::Cipher::CipherError => e
|
30
|
-
|
30
|
+
Kafkr.log "Decryption failed: #{e.message}"
|
31
31
|
nil
|
32
32
|
end
|
33
33
|
end
|
data/lib/kafkr/log.rb
CHANGED
@@ -27,7 +27,7 @@ module Kafkr
|
|
27
27
|
client_ip = client.peeraddr[3]
|
28
28
|
|
29
29
|
unless whitelisted?(client_ip)
|
30
|
-
|
30
|
+
Kafkr.log "Connection from non-whitelisted IP: #{client_ip}. Ignored."
|
31
31
|
client.close
|
32
32
|
next
|
33
33
|
end
|
@@ -35,27 +35,28 @@ module Kafkr
|
|
35
35
|
@broker.add_subscriber(client)
|
36
36
|
|
37
37
|
Thread.new do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
uuid, message_content = extract_uuid(message)
|
50
|
-
if uuid && message_content
|
51
|
-
@broker.broadcast(message_content)
|
38
|
+
|
39
|
+
|
40
|
+
begin
|
41
|
+
|
42
|
+
loop do
|
43
|
+
encrypted_message = client.gets
|
44
|
+
if encrypted_message.nil?
|
45
|
+
@broker.last_sent.delete(client)
|
46
|
+
client.close
|
47
|
+
@broker.subscribers.delete(client)
|
48
|
+
break
|
52
49
|
else
|
53
|
-
|
50
|
+
decryptor = Kafkr::Encryptor.new
|
51
|
+
message = decryptor.decrypt(encrypted_message.chomp) # Decrypt the message here
|
52
|
+
uuid, message_content = extract_uuid(message)
|
53
|
+
@broker.broadcast(message_content)
|
54
54
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
rescue Errno::ECONNRESET
|
56
|
+
client.close
|
57
|
+
end
|
58
|
+
rescue StandardError => exception
|
59
|
+
#TODO we need to find the place for a global exception handler
|
59
60
|
end
|
60
61
|
end
|
61
62
|
end
|
@@ -71,9 +72,10 @@ module Kafkr
|
|
71
72
|
# Check if message is valid JSON
|
72
73
|
begin
|
73
74
|
message = JSON.parse(message)
|
75
|
+
Kafkr.log ">> #{message}"
|
74
76
|
return message["uuid"], message
|
75
77
|
rescue JSON::ParserError => e
|
76
|
-
|
78
|
+
Kafkr.log ">> #{message}"
|
77
79
|
match_data = /^(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}): (.+)$/.match(message)
|
78
80
|
match_data ? [match_data[1], match_data[2]] : [nil, nil]
|
79
81
|
end
|
data/lib/kafkr/message_broker.rb
CHANGED
@@ -13,20 +13,22 @@ module Kafkr
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def broadcast(message)
|
16
|
-
Kafkr.
|
17
|
-
|
18
|
-
encrypted_message = Kafkr::Encryptor.new.encrypt(message)
|
19
|
-
|
16
|
+
encrypted_message = Kafkr::Encryptor.new.encrypt(message)
|
20
17
|
@subscribers.each do |subscriber|
|
21
18
|
if !subscriber.closed?
|
22
|
-
subscriber.
|
19
|
+
subscriber.Kafkr.log(encrypted_message)
|
23
20
|
@last_sent[subscriber] = encrypted_message
|
24
21
|
end
|
25
22
|
rescue Errno::EPIPE
|
26
23
|
# Optionally, handle broken pipe error
|
27
24
|
rescue IOError
|
28
|
-
|
29
|
-
|
25
|
+
begin
|
26
|
+
@subscribers.delete(subscriber)
|
27
|
+
@last_sent.delete(subscriber)
|
28
|
+
rescue
|
29
|
+
Kafkr.log "clean up subscribers"
|
30
|
+
end
|
31
|
+
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
data/lib/kafkr/producer.rb
CHANGED
@@ -50,6 +50,8 @@ module Kafkr
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def self.send_message(message)
|
53
|
+
return if message.nil? || message.empty?
|
54
|
+
|
53
55
|
uuid = SecureRandom.uuid
|
54
56
|
message_with_uuid = nil
|
55
57
|
|
@@ -73,13 +75,13 @@ module Kafkr
|
|
73
75
|
begin
|
74
76
|
socket = TCPSocket.new(@configuration.host, @configuration.port)
|
75
77
|
send_queued_messages(socket)
|
76
|
-
socket.
|
78
|
+
socket.Kafkr.log(encrypted_message_with_uuid)
|
77
79
|
rescue Errno::ECONNREFUSED
|
78
|
-
|
80
|
+
Kafkr.log "Connection refused. Queuing message: #{encrypted_message_with_uuid}"
|
79
81
|
@configuration.message_queue.push(encrypted_message_with_uuid)
|
80
82
|
save_queue_to_file
|
81
83
|
rescue Errno::EPIPE
|
82
|
-
|
84
|
+
Kafkr.log "Broken pipe error. Retrying connection..."
|
83
85
|
retry_connection(encrypted_message_with_uuid)
|
84
86
|
end
|
85
87
|
|
@@ -104,14 +106,14 @@ module Kafkr
|
|
104
106
|
def self.send_queued_messages(socket)
|
105
107
|
until @configuration.message_queue.empty?
|
106
108
|
queued_message = @configuration.message_queue.shift
|
107
|
-
socket.
|
109
|
+
socket.Kafkr.log(queued_message)
|
108
110
|
end
|
109
111
|
end
|
110
112
|
|
111
113
|
def self.save_queue_to_file
|
112
114
|
@@file_mutex.synchronize do
|
113
115
|
File.open(@configuration.queue_file, "w") do |file|
|
114
|
-
file.
|
116
|
+
file.Kafkr.log(@configuration.message_queue)
|
115
117
|
end
|
116
118
|
end
|
117
119
|
end
|
data/lib/kafkr/version.rb
CHANGED
data/lib/kafkr.rb
CHANGED
@@ -75,16 +75,7 @@ module Kafkr
|
|
75
75
|
|
76
76
|
def write(message, unique_id = nil)
|
77
77
|
begin
|
78
|
-
|
79
|
-
rescue => e
|
80
|
-
unique_id = "unknown"
|
81
|
-
@logger.error("Failed to generate UUID: #{e.message}")
|
82
|
-
end
|
83
|
-
formatted_message = "[#{unique_id}] #{message}"
|
84
|
-
|
85
|
-
begin
|
86
|
-
puts formatted_message if development?
|
87
|
-
logger.info(formatted_message)
|
78
|
+
logger.info(message)
|
88
79
|
rescue IOError => e
|
89
80
|
@logger.error("Failed to write log: #{e.message}")
|
90
81
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kafkr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.018.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delaney Kuldvee Burke
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gibberish
|