github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/rust/src/messaging/zmq_stream.rs (about) 1 /* 2 * Copyright 2017 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * ----------------------------------------------------------------------------- 16 */ 17 use uuid; 18 use zmq; 19 20 use std::collections::HashMap; 21 use std::error::Error; 22 use std::sync::mpsc::{channel, sync_channel, Receiver, RecvTimeoutError, Sender, SyncSender}; 23 use std::sync::{Arc, Mutex}; 24 use std::thread; 25 use std::time::Duration; 26 27 use messages::validator::Message; 28 use messages::validator::Message_MessageType; 29 use protobuf; 30 31 use messaging::stream::*; 32 33 /// A MessageConnection over ZMQ sockets 34 pub struct ZmqMessageConnection { 35 address: String, 36 context: zmq::Context, 37 } 38 39 const CHANNEL_BUFFER_SIZE: usize = 128; 40 41 impl ZmqMessageConnection { 42 /// Create a new ZmqMessageConnection 43 pub fn new(address: &str) -> Self { 44 ZmqMessageConnection { 45 address: String::from(address), 46 context: zmq::Context::new(), 47 } 48 } 49 } 50 51 impl MessageConnection<ZmqMessageSender> for ZmqMessageConnection { 52 fn create(&self) -> (ZmqMessageSender, MessageReceiver) { 53 // Create the channel for request messages (i.e. non-reply messages) 54 let (request_tx, request_rx) = sync_channel(CHANNEL_BUFFER_SIZE); 55 let router = InboundRouter::new(request_tx); 56 let mut sender = ZmqMessageSender::new(self.context.clone(), self.address.clone(), router); 57 58 sender.start(); 59 60 (sender, request_rx) 61 } 62 } 63 64 #[derive(Debug)] 65 enum SocketCommand { 66 Send(Message), 67 Shutdown, 68 } 69 70 #[derive(Clone)] 71 pub struct ZmqMessageSender { 72 context: zmq::Context, 73 address: String, 74 inbound_router: InboundRouter, 75 outbound_sender: Option<SyncSender<SocketCommand>>, 76 } 77 78 impl ZmqMessageSender { 79 fn new(ctx: zmq::Context, address: String, router: InboundRouter) -> Self { 80 ZmqMessageSender { 81 context: ctx, 82 address: address, 83 inbound_router: router, 84 outbound_sender: None, 85 } 86 } 87 88 /// Start the message stream instance 89 fn start(&mut self) { 90 let (outbound_send, outbound_recv) = sync_channel(CHANNEL_BUFFER_SIZE); 91 self.outbound_sender = Some(outbound_send); 92 93 let ctx = self.context.clone(); 94 let address = self.address.clone(); 95 let inbound_router = self.inbound_router.clone(); 96 thread::spawn(move || { 97 let mut inner_stream = 98 SendReceiveStream::new(&ctx, &address, outbound_recv, inbound_router); 99 inner_stream.run(); 100 }); 101 } 102 } 103 104 impl MessageSender for ZmqMessageSender { 105 fn send( 106 &mut self, 107 destination: Message_MessageType, 108 correlation_id: &str, 109 contents: &[u8], 110 ) -> Result<MessageFuture, SendError> { 111 if let Some(ref sender) = self.outbound_sender { 112 let mut msg = Message::new(); 113 114 msg.set_message_type(destination); 115 msg.set_correlation_id(String::from(correlation_id)); 116 msg.set_content(Vec::from(contents)); 117 118 let future = MessageFuture::new( 119 self.inbound_router 120 .expect_reply(String::from(correlation_id)), 121 ); 122 123 sender.send(SocketCommand::Send(msg)).unwrap(); 124 125 Ok(future) 126 } else { 127 Err(SendError::DisconnectedError) 128 } 129 } 130 131 fn reply( 132 &mut self, 133 destination: Message_MessageType, 134 correlation_id: &str, 135 contents: &[u8], 136 ) -> Result<(), SendError> { 137 if let Some(ref sender) = self.outbound_sender { 138 let mut msg = Message::new(); 139 msg.set_message_type(destination); 140 msg.set_correlation_id(String::from(correlation_id)); 141 msg.set_content(Vec::from(contents)); 142 143 match sender.send(SocketCommand::Send(msg)) { 144 Ok(_) => Ok(()), 145 Err(_) => Err(SendError::UnknownError), 146 } 147 } else { 148 Err(SendError::DisconnectedError) 149 } 150 } 151 152 fn close(&mut self) { 153 if let Some(ref sender) = self.outbound_sender.take() { 154 match sender.send(SocketCommand::Shutdown) { 155 Ok(_) => (), 156 Err(_) => info!("Sender has already closed."), 157 } 158 } 159 } 160 } 161 162 #[derive(Clone)] 163 struct InboundRouter { 164 inbound_tx: SyncSender<MessageResult>, 165 expected_replies: Arc<Mutex<HashMap<String, Sender<MessageResult>>>>, 166 } 167 168 impl InboundRouter { 169 fn new(inbound_tx: SyncSender<MessageResult>) -> Self { 170 InboundRouter { 171 inbound_tx: inbound_tx, 172 expected_replies: Arc::new(Mutex::new(HashMap::new())), 173 } 174 } 175 fn route(&mut self, message_result: MessageResult) { 176 match message_result { 177 Ok(message) => { 178 let mut expected_replies = self.expected_replies.lock().unwrap(); 179 match expected_replies.remove(message.get_correlation_id()) { 180 Some(sender) => sender.send(Ok(message)).expect("Unable to route reply"), 181 None => self.inbound_tx 182 .send(Ok(message)) 183 .expect("Unable to route new message"), 184 } 185 } 186 Err(ReceiveError::DisconnectedError) => { 187 let mut expected_replies = self.expected_replies.lock().unwrap(); 188 for (_, sender) in expected_replies.iter_mut() { 189 sender 190 .send(Err(ReceiveError::DisconnectedError)) 191 .unwrap_or_else(|err| error!("Failed to send disconnect reply: {}", err)); 192 } 193 self.inbound_tx 194 .send(Err(ReceiveError::DisconnectedError)) 195 .unwrap_or_else(|err| error!("Failed to send disconnect: {}", err)); 196 } 197 Err(err) => error!("Error: {}", err.description()), 198 } 199 } 200 201 fn expect_reply(&mut self, correlation_id: String) -> Receiver<MessageResult> { 202 let (expect_tx, expect_rx) = channel(); 203 let mut expected_replies = self.expected_replies.lock().unwrap(); 204 expected_replies.insert(correlation_id, expect_tx); 205 206 expect_rx 207 } 208 } 209 210 /// Internal stream, guarding a zmq socket. 211 struct SendReceiveStream { 212 address: String, 213 socket: zmq::Socket, 214 outbound_recv: Receiver<SocketCommand>, 215 inbound_router: InboundRouter, 216 monitor_socket: zmq::Socket, 217 } 218 219 const POLL_TIMEOUT: i64 = 10; 220 221 impl SendReceiveStream { 222 fn new( 223 context: &zmq::Context, 224 address: &str, 225 outbound_recv: Receiver<SocketCommand>, 226 inbound_router: InboundRouter, 227 ) -> Self { 228 let socket = context.socket(zmq::DEALER).unwrap(); 229 socket 230 .monitor( 231 "inproc://monitor-socket", 232 zmq::SocketEvent::DISCONNECTED as i32, 233 ) 234 .is_ok(); 235 let monitor_socket = context.socket(zmq::PAIR).unwrap(); 236 237 let identity = uuid::Uuid::new(uuid::UuidVersion::Random).unwrap(); 238 socket.set_identity(identity.as_bytes()).unwrap(); 239 240 SendReceiveStream { 241 address: String::from(address), 242 socket: socket, 243 outbound_recv: outbound_recv, 244 inbound_router: inbound_router, 245 monitor_socket: monitor_socket, 246 } 247 } 248 249 fn run(&mut self) { 250 self.socket.connect(&self.address).unwrap(); 251 self.monitor_socket 252 .connect("inproc://monitor-socket") 253 .unwrap(); 254 loop { 255 let mut poll_items = [ 256 self.socket.as_poll_item(zmq::POLLIN), 257 self.monitor_socket.as_poll_item(zmq::POLLIN), 258 ]; 259 zmq::poll(&mut poll_items, POLL_TIMEOUT).unwrap(); 260 if poll_items[0].is_readable() { 261 trace!("Readable!"); 262 let mut received_parts = self.socket.recv_multipart(0).unwrap(); 263 264 // Grab the last part, which should contain our message 265 if let Some(received_bytes) = received_parts.pop() { 266 trace!("Received {} bytes", received_bytes.len()); 267 if !received_bytes.is_empty() { 268 let message = protobuf::parse_from_bytes(&received_bytes).unwrap(); 269 self.inbound_router.route(Ok(message)); 270 } 271 } else { 272 debug!("Empty frame received."); 273 } 274 } 275 if poll_items[1].is_readable() { 276 self.monitor_socket.recv_multipart(0).unwrap(); 277 let message_result = Err(ReceiveError::DisconnectedError); 278 info!("Received Disconnect"); 279 self.inbound_router.route(message_result); 280 break; 281 } 282 283 match self.outbound_recv 284 .recv_timeout(Duration::from_millis(POLL_TIMEOUT as u64)) 285 { 286 Ok(SocketCommand::Send(msg)) => { 287 let message_bytes = protobuf::Message::write_to_bytes(&msg).unwrap(); 288 trace!("Sending {} bytes", message_bytes.len()); 289 self.socket.send(&message_bytes, 0).unwrap(); 290 } 291 Ok(SocketCommand::Shutdown) => { 292 trace!("Shutdown Signal Received"); 293 break; 294 } 295 Err(RecvTimeoutError::Disconnected) => { 296 debug!("Disconnected outbound channel"); 297 break; 298 } 299 _ => continue, 300 } 301 } 302 303 debug!("Exited stream"); 304 self.socket.disconnect(&self.address).unwrap(); 305 self.monitor_socket 306 .disconnect("inproc://monitor-socket") 307 .unwrap(); 308 } 309 }