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  }