github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/rust/src/messaging/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 messages::validator::Message;
    18  use messages::validator::Message_MessageType;
    19  use std;
    20  use std::error::Error;
    21  use std::sync::mpsc::Receiver;
    22  use std::sync::mpsc::RecvError;
    23  use std::time::Duration;
    24  
    25  /// A Message Sender
    26  ///
    27  /// A message
    28  pub trait MessageSender {
    29      fn send(
    30          &mut self,
    31          destination: Message_MessageType,
    32          correlation_id: &str,
    33          contents: &[u8],
    34      ) -> Result<MessageFuture, SendError>;
    35  
    36      fn reply(
    37          &mut self,
    38          destination: Message_MessageType,
    39          correlation_id: &str,
    40          contents: &[u8],
    41      ) -> Result<(), SendError>;
    42  
    43      fn close(&mut self);
    44  }
    45  
    46  /// Result for a message received.
    47  pub type MessageResult = Result<Message, ReceiveError>;
    48  
    49  /// A message Receiver
    50  pub type MessageReceiver = Receiver<MessageResult>;
    51  
    52  /// A Message Connection
    53  ///
    54  /// This denotes a connection which can create a MessageSender/Receiver pair.
    55  pub trait MessageConnection<MS: MessageSender> {
    56      fn create(&self) -> (MS, MessageReceiver);
    57  }
    58  
    59  /// Errors that occur on sending a message.
    60  #[derive(Debug)]
    61  pub enum SendError {
    62      DisconnectedError,
    63      TimeoutError,
    64      UnknownError,
    65  }
    66  
    67  impl std::error::Error for SendError {
    68      fn description(&self) -> &str {
    69          match *self {
    70              SendError::DisconnectedError => "DisconnectedError",
    71              SendError::TimeoutError => "TimeoutError",
    72              SendError::UnknownError => "UnknownError",
    73          }
    74      }
    75  
    76      fn cause(&self) -> Option<&std::error::Error> {
    77          match *self {
    78              SendError::DisconnectedError => None,
    79              SendError::TimeoutError => None,
    80              SendError::UnknownError => None,
    81          }
    82      }
    83  }
    84  
    85  impl std::fmt::Display for SendError {
    86      fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    87          match *self {
    88              SendError::DisconnectedError => write!(f, "DisconnectedError"),
    89              SendError::TimeoutError => write!(f, "TimeoutError"),
    90              SendError::UnknownError => write!(f, "UnknownError"),
    91          }
    92      }
    93  }
    94  
    95  /// Errors that occur on receiving a message.
    96  #[derive(Debug, Clone)]
    97  pub enum ReceiveError {
    98      TimeoutError,
    99      ChannelError(RecvError),
   100      DisconnectedError,
   101  }
   102  
   103  impl std::error::Error for ReceiveError {
   104      fn description(&self) -> &str {
   105          match *self {
   106              ReceiveError::TimeoutError => "TimeoutError",
   107              ReceiveError::ChannelError(ref err) => err.description(),
   108              ReceiveError::DisconnectedError => "DisconnectedError",
   109          }
   110      }
   111  
   112      fn cause(&self) -> Option<&std::error::Error> {
   113          match *self {
   114              ReceiveError::TimeoutError => None,
   115              ReceiveError::ChannelError(ref err) => Some(err),
   116              ReceiveError::DisconnectedError => None,
   117          }
   118      }
   119  }
   120  
   121  impl std::fmt::Display for ReceiveError {
   122      fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
   123          match *self {
   124              ReceiveError::TimeoutError => write!(f, "TimeoutError"),
   125              ReceiveError::ChannelError(ref err) => write!(f, "ChannelError: {}", err.description()),
   126              ReceiveError::DisconnectedError => write!(f, "DisconnectedError"),
   127          }
   128      }
   129  }
   130  /// MessageFuture is a promise for the reply to a sent message on connection.
   131  pub struct MessageFuture {
   132      inner: Receiver<MessageResult>,
   133      result: Option<MessageResult>,
   134  }
   135  
   136  impl MessageFuture {
   137      pub fn new(inner: Receiver<MessageResult>) -> Self {
   138          MessageFuture {
   139              inner: inner,
   140              result: None,
   141          }
   142      }
   143  
   144      pub fn get(&mut self) -> MessageResult {
   145          if let Some(ref result) = self.result {
   146              return result.clone();
   147          }
   148  
   149          match self.inner.recv() {
   150              Ok(result) => {
   151                  self.result = Some(result.clone());
   152                  result
   153              }
   154              Err(err) => Err(ReceiveError::ChannelError(err)),
   155          }
   156      }
   157  
   158      pub fn get_timeout(&mut self, timeout: Duration) -> MessageResult {
   159          if let Some(ref result) = self.result {
   160              return result.clone();
   161          }
   162  
   163          match self.inner.recv_timeout(timeout) {
   164              Ok(result) => {
   165                  self.result = Some(result.clone());
   166                  result
   167              }
   168              Err(_) => Err(ReceiveError::TimeoutError),
   169          }
   170      }
   171  }
   172  
   173  /// Queue for inbound messages, sent directly to this stream.
   174  
   175  #[cfg(test)]
   176  mod tests {
   177  
   178      use std::sync::mpsc::channel;
   179      use std::thread;
   180  
   181      use messages::validator::Message;
   182      use messages::validator::Message_MessageType;
   183  
   184      use super::MessageFuture;
   185  
   186      fn make_ping(correlation_id: &str) -> Message {
   187          let mut message = Message::new();
   188          message.set_message_type(Message_MessageType::PING_REQUEST);
   189          message.set_correlation_id(String::from(correlation_id));
   190          message.set_content(String::from("PING").into_bytes());
   191  
   192          message
   193      }
   194  
   195      #[test]
   196      fn future_get() {
   197          let (tx, rx) = channel();
   198  
   199          let mut fut = MessageFuture::new(rx);
   200  
   201          let t = thread::spawn(move || {
   202              tx.send(Ok(make_ping("my_test"))).unwrap();
   203          });
   204  
   205          let msg = fut.get().expect("Should have a message");
   206  
   207          t.join().unwrap();
   208  
   209          assert_eq!(msg, make_ping("my_test"));
   210      }
   211  }