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 }