pantry 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +9 -0
- data/.ruby-version +1 -0
- data/.travis.yml +19 -0
- data/Gemfile +15 -0
- data/Guardfile +16 -0
- data/LICENSE +20 -0
- data/README.md +53 -0
- data/Rakefile +18 -0
- data/Vagrantfile +86 -0
- data/bin/pantry +11 -0
- data/bin/pantry-client +38 -0
- data/bin/pantry-server +33 -0
- data/dist/client.yml +79 -0
- data/dist/server.yml +56 -0
- data/dist/upstart/pantry-client.conf +12 -0
- data/dist/upstart/pantry-server.conf +12 -0
- data/doc/message_packet.dot +19 -0
- data/doc/message_packet.dot.png +0 -0
- data/doc/network_topology.dot +42 -0
- data/doc/network_topology.dot.png +0 -0
- data/lib/celluloid_zmq_patches.rb +16 -0
- data/lib/opt_parse_plus.rb +184 -0
- data/lib/pantry.rb +197 -0
- data/lib/pantry/cli.rb +154 -0
- data/lib/pantry/client.rb +131 -0
- data/lib/pantry/client_info.rb +34 -0
- data/lib/pantry/client_registry.rb +104 -0
- data/lib/pantry/command.rb +194 -0
- data/lib/pantry/command_handler.rb +53 -0
- data/lib/pantry/command_line.rb +115 -0
- data/lib/pantry/commands/create_client.rb +30 -0
- data/lib/pantry/commands/download_directory.rb +35 -0
- data/lib/pantry/commands/echo.rb +32 -0
- data/lib/pantry/commands/edit_application.rb +60 -0
- data/lib/pantry/commands/register_client.rb +38 -0
- data/lib/pantry/commands/status.rb +78 -0
- data/lib/pantry/commands/sync_directory.rb +50 -0
- data/lib/pantry/commands/update_application.rb +45 -0
- data/lib/pantry/commands/upload_file.rb +68 -0
- data/lib/pantry/communication.rb +20 -0
- data/lib/pantry/communication/client.rb +75 -0
- data/lib/pantry/communication/client_filter.rb +117 -0
- data/lib/pantry/communication/file_service.rb +125 -0
- data/lib/pantry/communication/file_service/file_progress.rb +164 -0
- data/lib/pantry/communication/file_service/receive_file.rb +97 -0
- data/lib/pantry/communication/file_service/send_file.rb +74 -0
- data/lib/pantry/communication/publish_socket.rb +20 -0
- data/lib/pantry/communication/reading_socket.rb +89 -0
- data/lib/pantry/communication/receive_socket.rb +23 -0
- data/lib/pantry/communication/security.rb +44 -0
- data/lib/pantry/communication/security/authentication.rb +98 -0
- data/lib/pantry/communication/security/curve_key_store.rb +120 -0
- data/lib/pantry/communication/security/curve_security.rb +70 -0
- data/lib/pantry/communication/security/null_security.rb +32 -0
- data/lib/pantry/communication/send_socket.rb +19 -0
- data/lib/pantry/communication/serialize_message.rb +84 -0
- data/lib/pantry/communication/server.rb +97 -0
- data/lib/pantry/communication/subscribe_socket.rb +33 -0
- data/lib/pantry/communication/wait_list.rb +45 -0
- data/lib/pantry/communication/writing_socket.rb +46 -0
- data/lib/pantry/config.rb +182 -0
- data/lib/pantry/file_editor.rb +67 -0
- data/lib/pantry/logger.rb +78 -0
- data/lib/pantry/message.rb +134 -0
- data/lib/pantry/multi_command.rb +36 -0
- data/lib/pantry/server.rb +132 -0
- data/lib/pantry/test/acceptance.rb +83 -0
- data/lib/pantry/test/support/fake_fs.rb +31 -0
- data/lib/pantry/test/support/matchers.rb +13 -0
- data/lib/pantry/test/support/minitest.rb +13 -0
- data/lib/pantry/test/support/mock_ui.rb +23 -0
- data/lib/pantry/test/unit.rb +13 -0
- data/lib/pantry/ui.rb +68 -0
- data/lib/pantry/version.rb +3 -0
- data/pantry.gemspec +40 -0
- data/test/acceptance/cli/error_handling_test.rb +7 -0
- data/test/acceptance/cli/execute_command_on_clients_test.rb +32 -0
- data/test/acceptance/cli/request_info_from_server_test.rb +44 -0
- data/test/acceptance/communication/client_requests_info_from_server_test.rb +28 -0
- data/test/acceptance/communication/heartbeat_test.rb +19 -0
- data/test/acceptance/communication/pub_sub_communication_test.rb +53 -0
- data/test/acceptance/communication/security_test.rb +117 -0
- data/test/acceptance/communication/server_requests_info_from_client_test.rb +41 -0
- data/test/acceptance/test_helper.rb +25 -0
- data/test/fixtures/config.yml +22 -0
- data/test/fixtures/empty.yml +2 -0
- data/test/fixtures/file_to_upload +3 -0
- data/test/root_dir/.gitkeep +0 -0
- data/test/unit/cli_test.rb +173 -0
- data/test/unit/client_registry_test.rb +61 -0
- data/test/unit/client_test.rb +128 -0
- data/test/unit/command_handler_test.rb +79 -0
- data/test/unit/command_line_test.rb +5 -0
- data/test/unit/command_test.rb +206 -0
- data/test/unit/commands/create_client_test.rb +25 -0
- data/test/unit/commands/download_directory_test.rb +58 -0
- data/test/unit/commands/echo_test.rb +22 -0
- data/test/unit/commands/edit_application_test.rb +84 -0
- data/test/unit/commands/register_client_test.rb +41 -0
- data/test/unit/commands/status_test.rb +81 -0
- data/test/unit/commands/sync_directory_test.rb +75 -0
- data/test/unit/commands/update_application_test.rb +35 -0
- data/test/unit/commands/upload_file_test.rb +51 -0
- data/test/unit/communication/client_filter_test.rb +262 -0
- data/test/unit/communication/client_test.rb +99 -0
- data/test/unit/communication/file_service/receive_file_test.rb +214 -0
- data/test/unit/communication/file_service/send_file_test.rb +110 -0
- data/test/unit/communication/file_service_test.rb +56 -0
- data/test/unit/communication/publish_socket_test.rb +19 -0
- data/test/unit/communication/reading_socket_test.rb +110 -0
- data/test/unit/communication/receive_socket_test.rb +20 -0
- data/test/unit/communication/security/authentication_test.rb +97 -0
- data/test/unit/communication/security/curve_key_store_test.rb +110 -0
- data/test/unit/communication/security/curve_security_test.rb +44 -0
- data/test/unit/communication/security/null_security_test.rb +15 -0
- data/test/unit/communication/security_test.rb +49 -0
- data/test/unit/communication/send_socket_test.rb +19 -0
- data/test/unit/communication/serialize_message_test.rb +128 -0
- data/test/unit/communication/server_test.rb +106 -0
- data/test/unit/communication/subscribe_socket_test.rb +46 -0
- data/test/unit/communication/wait_list_test.rb +60 -0
- data/test/unit/communication/writing_socket_test.rb +46 -0
- data/test/unit/config_test.rb +150 -0
- data/test/unit/logger_test.rb +79 -0
- data/test/unit/message_test.rb +179 -0
- data/test/unit/multi_command_test.rb +45 -0
- data/test/unit/opt_parse_plus_test.rb +218 -0
- data/test/unit/pantry_test.rb +82 -0
- data/test/unit/server_test.rb +166 -0
- data/test/unit/test_helper.rb +25 -0
- data/test/unit/ui_test.rb +58 -0
- metadata +389 -13
@@ -0,0 +1,164 @@
|
|
1
|
+
module Pantry
|
2
|
+
module Communication
|
3
|
+
class FileService
|
4
|
+
|
5
|
+
# Informational object for keeping track of file upload progress and
|
6
|
+
# important information.
|
7
|
+
class UploadInfo
|
8
|
+
|
9
|
+
# Identity of the Receiver we're sending a file to
|
10
|
+
attr_accessor :receiver_uuid
|
11
|
+
|
12
|
+
# The file session identity from the Receiver
|
13
|
+
attr_accessor :file_uuid
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@finish_future = Celluloid::Future.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# Block and wait for the file upload to finish
|
20
|
+
def wait_for_finish(timeout = nil)
|
21
|
+
@finish_future.value(timeout)
|
22
|
+
end
|
23
|
+
|
24
|
+
def finished!
|
25
|
+
@finish_future.signal(OpenStruct.new(:value => self))
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sending-side version of UploadInfo
|
31
|
+
class SendingFile < UploadInfo
|
32
|
+
attr_reader :path, :file
|
33
|
+
|
34
|
+
def initialize(file_path, receiver_uuid, file_uuid)
|
35
|
+
super()
|
36
|
+
@path = file_path
|
37
|
+
@file_uuid = file_uuid
|
38
|
+
@file = File.open(@path, "r")
|
39
|
+
|
40
|
+
@receiver_uuid = receiver_uuid
|
41
|
+
|
42
|
+
@file_size = @file.size
|
43
|
+
@total_bytes_sent = 0
|
44
|
+
|
45
|
+
Pantry.ui.progress_start(@file_size)
|
46
|
+
end
|
47
|
+
|
48
|
+
def read(offset, bytes_to_read)
|
49
|
+
@total_bytes_sent += bytes_to_read
|
50
|
+
Pantry.ui.progress_step(bytes_to_read)
|
51
|
+
|
52
|
+
@file.seek(offset)
|
53
|
+
@file.read(bytes_to_read)
|
54
|
+
end
|
55
|
+
|
56
|
+
def finished!
|
57
|
+
Pantry.ui.progress_finish
|
58
|
+
|
59
|
+
@file.close
|
60
|
+
super
|
61
|
+
end
|
62
|
+
|
63
|
+
def finished?
|
64
|
+
@total_bytes_sent == @file_size || @file.closed?
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# Receiving-side version of UploadInfo
|
70
|
+
# Can be configured with a completion block that will be executed once the
|
71
|
+
# file has been fully received and checksum verified.
|
72
|
+
class ReceivingFile < UploadInfo
|
73
|
+
|
74
|
+
# Location of the tempfile containing the contents of the uploaded file
|
75
|
+
attr_reader :uploaded_path
|
76
|
+
|
77
|
+
attr_reader :file_size, :checksum, :uploaded_path
|
78
|
+
attr_accessor :sender_uuid
|
79
|
+
|
80
|
+
def initialize(file_size, checksum, chunk_size, pipeline_size)
|
81
|
+
super()
|
82
|
+
@file_uuid = SecureRandom.uuid
|
83
|
+
@file_size = file_size
|
84
|
+
@checksum = checksum
|
85
|
+
|
86
|
+
@chunk_size = chunk_size
|
87
|
+
@pipeline_size = pipeline_size
|
88
|
+
|
89
|
+
@uploaded_file = Tempfile.new(file_uuid)
|
90
|
+
@uploaded_path = @uploaded_file.path
|
91
|
+
|
92
|
+
@next_requested_file_offset = 0
|
93
|
+
@current_pipeline_size = 0
|
94
|
+
|
95
|
+
@chunk_count = (@file_size.to_f / @chunk_size.to_f).ceil
|
96
|
+
@requested_chunks = 0
|
97
|
+
@received_chunks = 0
|
98
|
+
end
|
99
|
+
|
100
|
+
def on_complete(&block)
|
101
|
+
@completion_block = block
|
102
|
+
end
|
103
|
+
|
104
|
+
def chunks_to_fetch(&block)
|
105
|
+
chunks_to_fill_pipeline = [
|
106
|
+
(@pipeline_size - @current_pipeline_size),
|
107
|
+
@chunk_count - @requested_chunks
|
108
|
+
].min
|
109
|
+
|
110
|
+
chunks_to_fill_pipeline.times do
|
111
|
+
block.call(@next_requested_file_offset, @chunk_size)
|
112
|
+
|
113
|
+
@next_requested_file_offset += @chunk_size
|
114
|
+
@current_pipeline_size += 1
|
115
|
+
@requested_chunks += 1
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def write_chunk(offset, size, data)
|
120
|
+
@current_pipeline_size -= 1
|
121
|
+
@received_chunks += 1
|
122
|
+
|
123
|
+
@uploaded_file.seek(offset)
|
124
|
+
@uploaded_file.write(data)
|
125
|
+
|
126
|
+
if @received_chunks == @chunk_count
|
127
|
+
@uploaded_file.close
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def finished!
|
132
|
+
@uploaded_file.close
|
133
|
+
|
134
|
+
if @completion_block && valid?
|
135
|
+
begin
|
136
|
+
@completion_block.call
|
137
|
+
rescue => ex
|
138
|
+
Pantry.logger.debug("[Receive File] Error running completion block #{ex.inspect}")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
super
|
143
|
+
end
|
144
|
+
|
145
|
+
def complete?
|
146
|
+
@uploaded_file.closed?
|
147
|
+
end
|
148
|
+
alias finished? complete?
|
149
|
+
|
150
|
+
def valid?
|
151
|
+
return @is_valid if defined?(@is_valid)
|
152
|
+
uploaded_checksum = Pantry.file_checksum(@uploaded_file.path)
|
153
|
+
@is_valid = (uploaded_checksum == @checksum)
|
154
|
+
end
|
155
|
+
|
156
|
+
def remove
|
157
|
+
@uploaded_file.unlink
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Pantry
|
2
|
+
module Communication
|
3
|
+
|
4
|
+
# Chunk file receiving tool that implements the protocol as described here
|
5
|
+
# http://zguide.zeromq.org/page:all#Transferring-Files
|
6
|
+
#
|
7
|
+
# In short, this tool requests chunks in a pipeline flow, writing out
|
8
|
+
# the received chunks to the file system at the given path.
|
9
|
+
class FileService::ReceiveFile
|
10
|
+
include Celluloid
|
11
|
+
|
12
|
+
attr_accessor :pipeline_size, :chunk_size
|
13
|
+
|
14
|
+
def initialize(service, chunk_size: 250_000, pipeline_size: 10)
|
15
|
+
@service = service
|
16
|
+
|
17
|
+
@chunk_size = chunk_size
|
18
|
+
@pipeline_size = pipeline_size
|
19
|
+
|
20
|
+
@receiving = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def receive_file(file_size, checksum)
|
24
|
+
FileService::ReceivingFile.new(
|
25
|
+
file_size, checksum, chunk_size, pipeline_size
|
26
|
+
).tap do |info|
|
27
|
+
@receiving[info.file_uuid] = info
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def receive_message(from_identity, message)
|
32
|
+
if current_file = @receiving[message.to]
|
33
|
+
current_file.sender_uuid = from_identity
|
34
|
+
else
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
case message.body[0]
|
39
|
+
when "START"
|
40
|
+
Pantry.logger.debug("[Receive File] Received START message #{message.inspect}")
|
41
|
+
fill_the_pipeline(current_file, message)
|
42
|
+
when "CHUNK"
|
43
|
+
Pantry.logger.debug("[Receive File] Received CHUNK message #{message.metadata}")
|
44
|
+
process_chunk(current_file, message)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def fill_the_pipeline(current_file, message)
|
51
|
+
current_file.chunks_to_fetch do |offset, size|
|
52
|
+
Pantry.logger.debug("[Receive File] Fetching #{offset} x #{size} for #{current_file.file_uuid}")
|
53
|
+
send_message(current_file, "FETCH", offset, size)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def process_chunk(current_file, message)
|
58
|
+
chunk_offset = message[:chunk_offset]
|
59
|
+
chunk_size = message[:chunk_size]
|
60
|
+
chunk_data = message.body[1]
|
61
|
+
|
62
|
+
current_file.write_chunk(chunk_offset, chunk_size, chunk_data)
|
63
|
+
|
64
|
+
if current_file.complete?
|
65
|
+
finalize_file(current_file)
|
66
|
+
else
|
67
|
+
fill_the_pipeline(current_file, message)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def finalize_file(current_file)
|
72
|
+
if current_file.valid?
|
73
|
+
Pantry.logger.debug("[Receive File] File #{current_file.file_uuid} finished")
|
74
|
+
send_message(current_file, "FINISH")
|
75
|
+
else
|
76
|
+
Pantry.logger.debug("[Receive File] File #{current_file.file_uuid} did not upload successfully")
|
77
|
+
current_file.remove
|
78
|
+
send_message(current_file, "ERROR", "Checksum did not match the uploaded file")
|
79
|
+
end
|
80
|
+
|
81
|
+
current_file.finished!
|
82
|
+
@receiving.delete(current_file.file_uuid)
|
83
|
+
end
|
84
|
+
|
85
|
+
def send_message(current_file, *body)
|
86
|
+
message = Pantry::Message.new
|
87
|
+
message.to = current_file.file_uuid
|
88
|
+
|
89
|
+
body.each {|part| message << part }
|
90
|
+
|
91
|
+
@service.send_message(current_file.sender_uuid, message)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Pantry
|
2
|
+
module Communication
|
3
|
+
|
4
|
+
# Chunk file sending tool that implements the protocol as described here
|
5
|
+
# http://zguide.zeromq.org/page:all#Transferring-Files
|
6
|
+
#
|
7
|
+
# As this actor receives chunk requests from the Receiver, it reads that chunk
|
8
|
+
# from the given file and sends it along.
|
9
|
+
class FileService::SendFile
|
10
|
+
include Celluloid
|
11
|
+
|
12
|
+
def initialize(service)
|
13
|
+
@service = service
|
14
|
+
@sending = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_file(file_path, receiver_uuid, file_uuid)
|
18
|
+
sender_info = FileService::SendingFile.new(file_path, receiver_uuid, file_uuid)
|
19
|
+
|
20
|
+
@sending[file_uuid] = sender_info
|
21
|
+
send_message(sender_info, "START")
|
22
|
+
|
23
|
+
sender_info
|
24
|
+
end
|
25
|
+
|
26
|
+
def receive_message(from_identity, message)
|
27
|
+
current_file_info = @sending[message.to]
|
28
|
+
return unless current_file_info
|
29
|
+
|
30
|
+
case message.body[0]
|
31
|
+
when "FETCH"
|
32
|
+
Pantry.logger.debug("[Send File] FETCH requested #{message.inspect}")
|
33
|
+
fetch_and_return_chunk(current_file_info, message)
|
34
|
+
when "FINISH"
|
35
|
+
Pantry.logger.debug("[Send File] FINISHED cleaning up for #{message.inspect}")
|
36
|
+
clean_up(current_file_info, message)
|
37
|
+
when "ERROR"
|
38
|
+
Pantry.logger.debug("[Send File] ERROR #{message.inspect}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def fetch_and_return_chunk(current_file, message)
|
45
|
+
chunk_offset = message.body[1].to_i
|
46
|
+
chunk_size = message.body[2].to_i
|
47
|
+
|
48
|
+
chunk = current_file.read(chunk_offset, chunk_size)
|
49
|
+
|
50
|
+
send_message(current_file, ["CHUNK", chunk], chunk_offset: chunk_offset, chunk_size: chunk_size)
|
51
|
+
end
|
52
|
+
|
53
|
+
def clean_up(current_file, message)
|
54
|
+
current_file.finished!
|
55
|
+
@sending.delete(message.to)
|
56
|
+
end
|
57
|
+
|
58
|
+
def send_message(sender_info, body, metadata = {})
|
59
|
+
message = Pantry::Message.new
|
60
|
+
message.to = sender_info.file_uuid
|
61
|
+
|
62
|
+
[body].flatten.each {|part| message << part }
|
63
|
+
|
64
|
+
metadata.each do |key, value|
|
65
|
+
message[key] = value
|
66
|
+
end
|
67
|
+
|
68
|
+
@service.send_message(sender_info.receiver_uuid, message)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Pantry
|
2
|
+
module Communication
|
3
|
+
|
4
|
+
# The PublishSocket handles the Publish side of Pub/Sub using
|
5
|
+
# a 0MQ PUB socket. Messages can be published to all listening clients
|
6
|
+
# or can be filtered to certain clients using a ClientFilter.
|
7
|
+
# See SubscribeSocket for the receiving end.
|
8
|
+
class PublishSocket < WritingSocket
|
9
|
+
|
10
|
+
def build_socket
|
11
|
+
Celluloid::ZMQ::PubSocket.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def open_socket(socket)
|
15
|
+
socket.bind("tcp://#{host}:#{port}")
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Pantry
|
2
|
+
module Communication
|
3
|
+
|
4
|
+
# Base class of all sockets that read messages from ZMQ.
|
5
|
+
# Not meant for direct use, please use one of the subclasses for specific
|
6
|
+
# functionality.
|
7
|
+
class ReadingSocket
|
8
|
+
include Celluloid::ZMQ
|
9
|
+
finalizer :shutdown
|
10
|
+
|
11
|
+
attr_reader :host, :port
|
12
|
+
|
13
|
+
def initialize(host, port, security)
|
14
|
+
@host = host
|
15
|
+
@port = port
|
16
|
+
@listener = nil
|
17
|
+
@security = security
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_listener(listener)
|
21
|
+
@listener = listener
|
22
|
+
end
|
23
|
+
|
24
|
+
def open
|
25
|
+
@socket = build_socket
|
26
|
+
Communication.configure_socket(@socket)
|
27
|
+
@security.configure_socket(@socket)
|
28
|
+
open_socket(@socket)
|
29
|
+
|
30
|
+
@running = true
|
31
|
+
self.async.process_messages
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_socket
|
35
|
+
raise "Implement the socket setup."
|
36
|
+
end
|
37
|
+
|
38
|
+
def open_socket(socket)
|
39
|
+
raise "Connect / Bind the socket built in #build_socket"
|
40
|
+
end
|
41
|
+
|
42
|
+
def shutdown
|
43
|
+
@running = false
|
44
|
+
end
|
45
|
+
|
46
|
+
# Some ZMQ socket types include the source as the first packet of a message.
|
47
|
+
# We need to know if the socket in question does this so we can properly
|
48
|
+
# build the Message coming in.
|
49
|
+
def has_source_header?
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def process_messages
|
56
|
+
while @running
|
57
|
+
process_next_message
|
58
|
+
end
|
59
|
+
|
60
|
+
@socket.close
|
61
|
+
end
|
62
|
+
|
63
|
+
def process_next_message
|
64
|
+
next_message = []
|
65
|
+
|
66
|
+
# Drop the ZMQ given source packet, it's extraneous for our purposes
|
67
|
+
if has_source_header?
|
68
|
+
@socket.read
|
69
|
+
end
|
70
|
+
|
71
|
+
next_message << @socket.read
|
72
|
+
|
73
|
+
while @socket.more_parts?
|
74
|
+
next_message << @socket.read
|
75
|
+
end
|
76
|
+
|
77
|
+
async.handle_message(
|
78
|
+
SerializeMessage.from_zeromq(next_message)
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
def handle_message(message)
|
83
|
+
@listener.handle_message(message) if @listener
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Pantry
|
2
|
+
module Communication
|
3
|
+
|
4
|
+
# The ReceiveSocket receives communication from Clients via the
|
5
|
+
# Dealer / Router socket pair. This class is the Server's Router side.
|
6
|
+
class ReceiveSocket < ReadingSocket
|
7
|
+
|
8
|
+
def build_socket
|
9
|
+
Celluloid::ZMQ::RouterSocket.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def open_socket(socket)
|
13
|
+
socket.bind("tcp://#{host}:#{port}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_source_header?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|