From f3eabf463a26f2f652db8915cca241b9e0cc9495 Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Wed, 4 Dec 2019 14:32:34 +0800 Subject: [PATCH 01/10] rustfmt. --- rustfmt.toml | 1 + src/errors.rs | 58 +++--- src/frame/cancel.rs | 16 +- src/frame/error.rs | 108 +++++------ src/frame/keepalive.rs | 116 ++++++------ src/frame/lease.rs | 140 +++++++------- src/frame/metadata_push.rs | 80 ++++---- src/frame/mod.rs | 266 +++++++++++++------------- src/frame/payload.rs | 102 +++++----- src/frame/request_channel.rs | 126 ++++++------ src/frame/request_fnf.rs | 102 +++++----- src/frame/request_n.rs | 76 ++++---- src/frame/request_response.rs | 102 +++++----- src/frame/request_stream.rs | 120 ++++++------ src/frame/resume.rs | 192 +++++++++---------- src/frame/resume_ok.rs | 74 ++++---- src/frame/setup.rs | 348 +++++++++++++++++----------------- src/frame/utils.rs | 116 ++++++------ src/frame/version.rs | 36 ++-- src/payload/default.rs | 156 +++++++-------- src/payload/setup.rs | 202 ++++++++++---------- src/transport/codec.rs | 54 +++--- src/transport/spi.rs | 16 +- src/transport/tcp.rs | 36 ++-- src/x/client.rs | 206 ++++++++++---------- src/x/factory.rs | 12 +- src/x/mod.rs | 2 +- src/x/server.rs | 90 ++++----- src/x/uri.rs | 4 +- tests/frames.rs | 144 +++++++------- 30 files changed, 1553 insertions(+), 1548 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..32a9786 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +edition = "2018" diff --git a/src/errors.rs b/src/errors.rs index 7aa6efd..70f24fd 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,55 +4,55 @@ use std::io; #[derive(Debug)] pub enum ErrorKind { - Internal(u32, &'static str), - WithDescription(String), - IO(io::Error), - Cancelled(), - Send(), + Internal(u32, &'static str), + WithDescription(String), + IO(io::Error), + Cancelled(), + Send(), } #[derive(Debug)] pub struct RSocketError { - kind: ErrorKind, + kind: ErrorKind, } impl Error for RSocketError { - fn description(&self) -> &str { - "this is a rsocket error" - } + fn description(&self) -> &str { + "this is a rsocket error" + } - fn cause(&self) -> Option<&dyn Error> { - match &self.kind { - ErrorKind::IO(e) => Some(e), - _ => None, + fn cause(&self) -> Option<&dyn Error> { + match &self.kind { + ErrorKind::IO(e) => Some(e), + _ => None, + } } - } } impl fmt::Display for RSocketError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - println!(">>>>>>>>>>> {:?}", self.kind); - unimplemented!() - } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + println!(">>>>>>>>>>> {:?}", self.kind); + unimplemented!() + } } impl From for RSocketError { - fn from(kind: ErrorKind) -> RSocketError { - RSocketError { kind } - } + fn from(kind: ErrorKind) -> RSocketError { + RSocketError { kind } + } } impl From for RSocketError { - fn from(e: String) -> RSocketError { - RSocketError { - kind: ErrorKind::WithDescription(e), + fn from(e: String) -> RSocketError { + RSocketError { + kind: ErrorKind::WithDescription(e), + } } - } } impl From<&'static str> for RSocketError { - fn from(e: &'static str) -> RSocketError { - RSocketError { - kind: ErrorKind::WithDescription(String::from(e)), + fn from(e: &'static str) -> RSocketError { + RSocketError { + kind: ErrorKind::WithDescription(String::from(e)), + } } - } } diff --git a/src/frame/cancel.rs b/src/frame/cancel.rs index 470c55a..817fd67 100644 --- a/src/frame/cancel.rs +++ b/src/frame/cancel.rs @@ -4,18 +4,18 @@ use super::{Body, Frame}; pub struct Cancel {} pub struct CancelBuilder { - stream_id: u32, - flag: u16, + stream_id: u32, + flag: u16, } impl CancelBuilder { - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::Cancel(), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::Cancel(), self.flag) + } } impl Cancel { - pub fn builder(stream_id: u32, flag: u16) -> CancelBuilder { - CancelBuilder { stream_id, flag } - } + pub fn builder(stream_id: u32, flag: u16) -> CancelBuilder { + CancelBuilder { stream_id, flag } + } } diff --git a/src/frame/error.rs b/src/frame/error.rs index d49a35b..4cafe34 100644 --- a/src/frame/error.rs +++ b/src/frame/error.rs @@ -4,80 +4,80 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct Error { - code: u32, - data: Option, + code: u32, + data: Option, } pub struct ErrorBuilder { - stream_id: u32, - flag: u16, - value: Error, + stream_id: u32, + flag: u16, + value: Error, } impl ErrorBuilder { - fn new(stream_id: u32, flag: u16) -> ErrorBuilder { - ErrorBuilder { - stream_id, - flag, - value: Error { - code: 0, - data: None, - }, + fn new(stream_id: u32, flag: u16) -> ErrorBuilder { + ErrorBuilder { + stream_id, + flag, + value: Error { + code: 0, + data: None, + }, + } } - } - pub fn set_code(mut self, code: u32) -> Self { - self.value.code = code; - self - } + pub fn set_code(mut self, code: u32) -> Self { + self.value.code = code; + self + } - pub fn set_data(mut self, data: Bytes) -> Self { - self.value.data = Some(data); - self - } + pub fn set_data(mut self, data: Bytes) -> Self { + self.value.data = Some(data); + self + } - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::Error(self.value), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::Error(self.value), self.flag) + } } impl Error { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let code = bf.get_u32(); - let d: Option = if !bf.is_empty() { - Some(bf.to_bytes()) - } else { - None - }; - Ok(Error { code, data: d }) - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let code = bf.get_u32(); + let d: Option = if !bf.is_empty() { + Some(bf.to_bytes()) + } else { + None + }; + Ok(Error { code, data: d }) + } - pub fn builder(stream_id: u32, flag: u16) -> ErrorBuilder { - ErrorBuilder::new(stream_id, flag) - } + pub fn builder(stream_id: u32, flag: u16) -> ErrorBuilder { + ErrorBuilder::new(stream_id, flag) + } - pub fn get_data(&self) -> &Option { - &self.data - } + pub fn get_data(&self) -> &Option { + &self.data + } - pub fn get_code(&self) -> u32 { - self.code - } + pub fn get_code(&self) -> u32 { + self.code + } } impl Writeable for Error { - fn write_to(&self, bf: &mut BytesMut) { - bf.put_u32(self.code); - match &self.data { - Some(v) => bf.put(v.bytes()), - None => (), + fn write_to(&self, bf: &mut BytesMut) { + bf.put_u32(self.code); + match &self.data { + Some(v) => bf.put(v.bytes()), + None => (), + } } - } - fn len(&self) -> usize { - 4 + match &self.data { - Some(v) => v.len(), - None => 0, + fn len(&self) -> usize { + 4 + match &self.data { + Some(v) => v.len(), + None => 0, + } } - } } diff --git a/src/frame/keepalive.rs b/src/frame/keepalive.rs index a3f9453..61c11ac 100644 --- a/src/frame/keepalive.rs +++ b/src/frame/keepalive.rs @@ -4,86 +4,86 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct Keepalive { - last_received_position: u64, - data: Option, + last_received_position: u64, + data: Option, } pub struct KeepaliveBuilder { - stream_id: u32, - flag: u16, - keepalive: Keepalive, + stream_id: u32, + flag: u16, + keepalive: Keepalive, } impl KeepaliveBuilder { - fn new(stream_id: u32, flag: u16) -> KeepaliveBuilder { - KeepaliveBuilder { - stream_id, - flag, - keepalive: Keepalive { - last_received_position: 0, - data: None, - }, + fn new(stream_id: u32, flag: u16) -> KeepaliveBuilder { + KeepaliveBuilder { + stream_id, + flag, + keepalive: Keepalive { + last_received_position: 0, + data: None, + }, + } } - } - pub fn set_data(mut self, data: Bytes) -> Self { - self.keepalive.data = Some(data); - self - } + pub fn set_data(mut self, data: Bytes) -> Self { + self.keepalive.data = Some(data); + self + } - pub fn set_last_received_position(mut self, position: u64) -> Self { - self.keepalive.last_received_position = position; - self - } + pub fn set_last_received_position(mut self, position: u64) -> Self { + self.keepalive.last_received_position = position; + self + } - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::Keepalive(self.keepalive), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::Keepalive(self.keepalive), self.flag) + } } impl Keepalive { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let position = bf.get_u64(); - let mut d: Option = None; - if !bf.is_empty() { - d = Some(bf.to_bytes()); + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let position = bf.get_u64(); + let mut d: Option = None; + if !bf.is_empty() { + d = Some(bf.to_bytes()); + } + Ok(Keepalive { + last_received_position: position, + data: d, + }) } - Ok(Keepalive { - last_received_position: position, - data: d, - }) - } - pub fn builder(stream_id: u32, flag: u16) -> KeepaliveBuilder { - KeepaliveBuilder::new(stream_id, flag) - } + pub fn builder(stream_id: u32, flag: u16) -> KeepaliveBuilder { + KeepaliveBuilder::new(stream_id, flag) + } - pub fn get_last_received_position(&self) -> u64 { - self.last_received_position - } + pub fn get_last_received_position(&self) -> u64 { + self.last_received_position + } - pub fn get_data(&self) -> &Option { - &self.data - } + pub fn get_data(&self) -> &Option { + &self.data + } - pub fn split(self) -> (Option, Option) { - (self.data, None) - } + pub fn split(self) -> (Option, Option) { + (self.data, None) + } } impl Writeable for Keepalive { - fn write_to(&self, bf: &mut BytesMut) { - bf.put_u64(self.last_received_position); - match &self.data { - Some(v) => bf.put(v.bytes()), - None => (), + fn write_to(&self, bf: &mut BytesMut) { + bf.put_u64(self.last_received_position); + match &self.data { + Some(v) => bf.put(v.bytes()), + None => (), + } } - } - fn len(&self) -> usize { - 8 + match &self.data { - Some(v) => v.len(), - None => 0, + fn len(&self) -> usize { + 8 + match &self.data { + Some(v) => v.len(), + None => 0, + } } - } } diff --git a/src/frame/lease.rs b/src/frame/lease.rs index c89d50f..0ba6841 100644 --- a/src/frame/lease.rs +++ b/src/frame/lease.rs @@ -4,98 +4,98 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct Lease { - ttl: u32, - number_of_requests: u32, - metadata: Option, + ttl: u32, + number_of_requests: u32, + metadata: Option, } pub struct LeaseBuilder { - stream_id: u32, - flag: u16, - value: Lease, + stream_id: u32, + flag: u16, + value: Lease, } impl LeaseBuilder { - fn new(stream_id: u32, flag: u16) -> LeaseBuilder { - LeaseBuilder { - stream_id, - flag, - value: Lease { - ttl: 0, - number_of_requests: 0, - metadata: None, - }, + fn new(stream_id: u32, flag: u16) -> LeaseBuilder { + LeaseBuilder { + stream_id, + flag, + value: Lease { + ttl: 0, + number_of_requests: 0, + metadata: None, + }, + } } - } - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.value.metadata = Some(metadata); - self.flag |= FLAG_METADATA; - self - } + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.value.metadata = Some(metadata); + self.flag |= FLAG_METADATA; + self + } - pub fn set_ttl(mut self, ttl: u32) -> Self { - self.value.ttl = ttl; - self - } + pub fn set_ttl(mut self, ttl: u32) -> Self { + self.value.ttl = ttl; + self + } - pub fn set_number_of_requests(mut self, n: u32) -> Self { - self.value.number_of_requests = n; - self - } + pub fn set_number_of_requests(mut self, n: u32) -> Self { + self.value.number_of_requests = n; + self + } - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::Lease(self.value), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::Lease(self.value), self.flag) + } } impl Lease { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let ttl = bf.get_u32(); - let n = bf.get_u32(); - let m = if flag & FLAG_METADATA != 0 { - Some(bf.to_bytes()) - } else { - None - }; - Ok(Lease { - ttl, - number_of_requests: n, - metadata: m, - }) - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let ttl = bf.get_u32(); + let n = bf.get_u32(); + let m = if flag & FLAG_METADATA != 0 { + Some(bf.to_bytes()) + } else { + None + }; + Ok(Lease { + ttl, + number_of_requests: n, + metadata: m, + }) + } - pub fn builder(stream_id: u32, flag: u16) -> LeaseBuilder { - LeaseBuilder::new(stream_id, flag) - } + pub fn builder(stream_id: u32, flag: u16) -> LeaseBuilder { + LeaseBuilder::new(stream_id, flag) + } - pub fn get_number_of_requests(&self) -> u32 { - self.number_of_requests - } + pub fn get_number_of_requests(&self) -> u32 { + self.number_of_requests + } - pub fn get_metadata(&self) -> &Option { - &self.metadata - } + pub fn get_metadata(&self) -> &Option { + &self.metadata + } - pub fn get_ttl(&self) -> u32 { - self.ttl - } + pub fn get_ttl(&self) -> u32 { + self.ttl + } } impl Writeable for Lease { - fn write_to(&self, bf: &mut BytesMut) { - bf.put_u32(self.ttl); - bf.put_u32(self.number_of_requests); - match &self.metadata { - Some(v) => bf.put(v.bytes()), - None => (), + fn write_to(&self, bf: &mut BytesMut) { + bf.put_u32(self.ttl); + bf.put_u32(self.number_of_requests); + match &self.metadata { + Some(v) => bf.put(v.bytes()), + None => (), + } } - } - fn len(&self) -> usize { - 8 + match &self.metadata { - Some(v) => v.len(), - None => 0, + fn len(&self) -> usize { + 8 + match &self.metadata { + Some(v) => v.len(), + None => 0, + } } - } } diff --git a/src/frame/metadata_push.rs b/src/frame/metadata_push.rs index 1d3011d..03a8488 100644 --- a/src/frame/metadata_push.rs +++ b/src/frame/metadata_push.rs @@ -4,65 +4,65 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct MetadataPush { - metadata: Option, + metadata: Option, } pub struct MetadataPushBuiler { - stream_id: u32, - flag: u16, - value: MetadataPush, + stream_id: u32, + flag: u16, + value: MetadataPush, } impl MetadataPushBuiler { - fn new(stream_id: u32, flag: u16) -> MetadataPushBuiler { - MetadataPushBuiler { - stream_id, - flag, - value: MetadataPush { metadata: None }, + fn new(stream_id: u32, flag: u16) -> MetadataPushBuiler { + MetadataPushBuiler { + stream_id, + flag, + value: MetadataPush { metadata: None }, + } } - } - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.value.metadata = Some(metadata); - self - } + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.value.metadata = Some(metadata); + self + } - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::MetadataPush(self.value), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::MetadataPush(self.value), self.flag) + } } impl MetadataPush { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let m = Bytes::from(bf.to_vec()); - Ok(MetadataPush { metadata: Some(m) }) - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let m = Bytes::from(bf.to_vec()); + Ok(MetadataPush { metadata: Some(m) }) + } - pub fn builder(stream_id: u32, flag: u16) -> MetadataPushBuiler { - MetadataPushBuiler::new(stream_id, flag) - } + pub fn builder(stream_id: u32, flag: u16) -> MetadataPushBuiler { + MetadataPushBuiler::new(stream_id, flag) + } - pub fn get_metadata(&self) -> &Option { - &self.metadata - } + pub fn get_metadata(&self) -> &Option { + &self.metadata + } - pub fn split(self) -> (Option, Option) { - (None, self.metadata) - } + pub fn split(self) -> (Option, Option) { + (None, self.metadata) + } } impl Writeable for MetadataPush { - fn write_to(&self, bf: &mut BytesMut) { - match &self.metadata { - Some(v) => bf.put(v.bytes()), - None => (), + fn write_to(&self, bf: &mut BytesMut) { + match &self.metadata { + Some(v) => bf.put(v.bytes()), + None => (), + } } - } - fn len(&self) -> usize { - match &self.metadata { - Some(v) => v.len(), - None => 0, + fn len(&self) -> usize { + match &self.metadata { + Some(v) => v.len(), + None => 0, + } } - } } diff --git a/src/frame/mod.rs b/src/frame/mod.rs index 09e291c..4ae6cd1 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -76,156 +76,156 @@ pub const REQUEST_MAX: u32 = 0x7FFF_FFFF; // 2147483647 const LEN_HEADER: usize = 6; pub trait Writeable { - fn write_to(&self, bf: &mut BytesMut); - fn len(&self) -> usize; - fn is_empty(&self) -> bool { - self.len() == 0 - } + fn write_to(&self, bf: &mut BytesMut); + fn len(&self) -> usize; + fn is_empty(&self) -> bool { + self.len() == 0 + } } #[derive(Debug, PartialEq)] pub enum Body { - Setup(Setup), - Lease(Lease), - Keepalive(Keepalive), - RequestFNF(RequestFNF), - RequestResponse(RequestResponse), - RequestStream(RequestStream), - RequestChannel(RequestChannel), - RequestN(RequestN), - Cancel(), - Payload(Payload), - Error(Error), - MetadataPush(MetadataPush), - Resume(Resume), - ResumeOK(ResumeOK), + Setup(Setup), + Lease(Lease), + Keepalive(Keepalive), + RequestFNF(RequestFNF), + RequestResponse(RequestResponse), + RequestStream(RequestStream), + RequestChannel(RequestChannel), + RequestN(RequestN), + Cancel(), + Payload(Payload), + Error(Error), + MetadataPush(MetadataPush), + Resume(Resume), + ResumeOK(ResumeOK), } #[derive(Debug, PartialEq)] pub struct Frame { - stream_id: u32, - body: Body, - flag: u16, + stream_id: u32, + body: Body, + flag: u16, } impl Writeable for Frame { - fn write_to(&self, bf: &mut BytesMut) { - bf.put_u32(self.stream_id); - bf.put_u16((to_frame_type(&self.body) << 10) | self.flag); - match &self.body { - Body::Setup(v) => v.write_to(bf), - Body::RequestResponse(v) => v.write_to(bf), - Body::RequestStream(v) => v.write_to(bf), - Body::RequestChannel(v) => v.write_to(bf), - Body::RequestFNF(v) => v.write_to(bf), - Body::RequestN(v) => v.write_to(bf), - Body::MetadataPush(v) => v.write_to(bf), - Body::Keepalive(v) => v.write_to(bf), - Body::Payload(v) => v.write_to(bf), - Body::Lease(v) => v.write_to(bf), - Body::Error(v) => v.write_to(bf), - Body::Cancel() => (), - Body::ResumeOK(v) => v.write_to(bf), - Body::Resume(v) => v.write_to(bf), + fn write_to(&self, bf: &mut BytesMut) { + bf.put_u32(self.stream_id); + bf.put_u16((to_frame_type(&self.body) << 10) | self.flag); + match &self.body { + Body::Setup(v) => v.write_to(bf), + Body::RequestResponse(v) => v.write_to(bf), + Body::RequestStream(v) => v.write_to(bf), + Body::RequestChannel(v) => v.write_to(bf), + Body::RequestFNF(v) => v.write_to(bf), + Body::RequestN(v) => v.write_to(bf), + Body::MetadataPush(v) => v.write_to(bf), + Body::Keepalive(v) => v.write_to(bf), + Body::Payload(v) => v.write_to(bf), + Body::Lease(v) => v.write_to(bf), + Body::Error(v) => v.write_to(bf), + Body::Cancel() => (), + Body::ResumeOK(v) => v.write_to(bf), + Body::Resume(v) => v.write_to(bf), + } + } + + fn len(&self) -> usize { + // header len + LEN_HEADER + + match &self.body { + Body::Setup(v) => v.len(), + Body::RequestResponse(v) => v.len(), + Body::RequestStream(v) => v.len(), + Body::RequestChannel(v) => v.len(), + Body::RequestFNF(v) => v.len(), + Body::RequestN(v) => v.len(), + Body::MetadataPush(v) => v.len(), + Body::Keepalive(v) => v.len(), + Body::Payload(v) => v.len(), + Body::Lease(v) => v.len(), + Body::Cancel() => 0, + Body::Error(v) => v.len(), + Body::ResumeOK(v) => v.len(), + Body::Resume(v) => v.len(), + } } - } - - fn len(&self) -> usize { - // header len - LEN_HEADER - + match &self.body { - Body::Setup(v) => v.len(), - Body::RequestResponse(v) => v.len(), - Body::RequestStream(v) => v.len(), - Body::RequestChannel(v) => v.len(), - Body::RequestFNF(v) => v.len(), - Body::RequestN(v) => v.len(), - Body::MetadataPush(v) => v.len(), - Body::Keepalive(v) => v.len(), - Body::Payload(v) => v.len(), - Body::Lease(v) => v.len(), - Body::Cancel() => 0, - Body::Error(v) => v.len(), - Body::ResumeOK(v) => v.len(), - Body::Resume(v) => v.len(), - } - } } impl Frame { - pub fn new(stream_id: u32, body: Body, flag: u16) -> Frame { - Frame { - stream_id, - body, - flag, + pub fn new(stream_id: u32, body: Body, flag: u16) -> Frame { + Frame { + stream_id, + body, + flag, + } + } + + pub fn decode(b: &mut BytesMut) -> RSocketResult { + // TODO: check size + let sid = b.get_u32(); + let n = b.get_u16(); + let (flag, kind) = (n & 0x03FF, (n & 0xFC00) >> 10); + let body = match kind { + TYPE_SETUP => Setup::decode(flag, b).map(Body::Setup), + TYPE_REQUEST_RESPONSE => RequestResponse::decode(flag, b).map(Body::RequestResponse), + TYPE_REQUEST_STREAM => RequestStream::decode(flag, b).map(Body::RequestStream), + TYPE_REQUEST_CHANNEL => RequestChannel::decode(flag, b).map(Body::RequestChannel), + TYPE_REQUEST_FNF => RequestFNF::decode(flag, b).map(Body::RequestFNF), + TYPE_REQUEST_N => RequestN::decode(flag, b).map(Body::RequestN), + TYPE_METADATA_PUSH => MetadataPush::decode(flag, b).map(Body::MetadataPush), + TYPE_KEEPALIVE => Keepalive::decode(flag, b).map(Body::Keepalive), + TYPE_PAYLOAD => Payload::decode(flag, b).map(Body::Payload), + TYPE_LEASE => Lease::decode(flag, b).map(Body::Lease), + TYPE_CANCEL => Ok(Body::Cancel()), + TYPE_ERROR => Error::decode(flag, b).map(Body::Error), + TYPE_RESUME_OK => ResumeOK::decode(flag, b).map(Body::ResumeOK), + TYPE_RESUME => Resume::decode(flag, b).map(Body::Resume), + _ => Err(RSocketError::from("illegal frame type")), + }; + body.map(|it| Frame::new(sid, it, flag)) + } + + pub fn get_body(self) -> Body { + self.body + } + + pub fn get_frame_type(&self) -> u16 { + to_frame_type(&self.body) + } + + pub fn get_flag(&self) -> u16 { + self.flag + } + + pub fn get_stream_id(&self) -> u32 { + self.stream_id + } + + pub fn has_next(&self) -> bool { + self.flag & FLAG_NEXT != 0 + } + + pub fn has_complete(&self) -> bool { + self.flag & FLAG_COMPLETE != 0 } - } - - pub fn decode(b: &mut BytesMut) -> RSocketResult { - // TODO: check size - let sid = b.get_u32(); - let n = b.get_u16(); - let (flag, kind) = (n & 0x03FF, (n & 0xFC00) >> 10); - let body = match kind { - TYPE_SETUP => Setup::decode(flag, b).map(Body::Setup), - TYPE_REQUEST_RESPONSE => RequestResponse::decode(flag, b).map(Body::RequestResponse), - TYPE_REQUEST_STREAM => RequestStream::decode(flag, b).map(Body::RequestStream), - TYPE_REQUEST_CHANNEL => RequestChannel::decode(flag, b).map(Body::RequestChannel), - TYPE_REQUEST_FNF => RequestFNF::decode(flag, b).map(Body::RequestFNF), - TYPE_REQUEST_N => RequestN::decode(flag, b).map(Body::RequestN), - TYPE_METADATA_PUSH => MetadataPush::decode(flag, b).map(Body::MetadataPush), - TYPE_KEEPALIVE => Keepalive::decode(flag, b).map(Body::Keepalive), - TYPE_PAYLOAD => Payload::decode(flag, b).map(Body::Payload), - TYPE_LEASE => Lease::decode(flag, b).map(Body::Lease), - TYPE_CANCEL => Ok(Body::Cancel()), - TYPE_ERROR => Error::decode(flag, b).map(Body::Error), - TYPE_RESUME_OK => ResumeOK::decode(flag, b).map(Body::ResumeOK), - TYPE_RESUME => Resume::decode(flag, b).map(Body::Resume), - _ => Err(RSocketError::from("illegal frame type")), - }; - body.map(|it| Frame::new(sid, it, flag)) - } - - pub fn get_body(self) -> Body { - self.body - } - - pub fn get_frame_type(&self) -> u16 { - to_frame_type(&self.body) - } - - pub fn get_flag(&self) -> u16 { - self.flag - } - - pub fn get_stream_id(&self) -> u32 { - self.stream_id - } - - pub fn has_next(&self) -> bool { - self.flag & FLAG_NEXT != 0 - } - - pub fn has_complete(&self) -> bool { - self.flag & FLAG_COMPLETE != 0 - } } fn to_frame_type(body: &Body) -> u16 { - match body { - Body::Setup(_) => TYPE_SETUP, - Body::Lease(_) => TYPE_LEASE, - Body::Keepalive(_) => TYPE_KEEPALIVE, - Body::RequestResponse(_) => TYPE_REQUEST_RESPONSE, - Body::RequestFNF(_) => TYPE_REQUEST_FNF, - Body::RequestStream(_) => TYPE_REQUEST_STREAM, - Body::RequestChannel(_) => TYPE_REQUEST_CHANNEL, - Body::RequestN(_) => TYPE_REQUEST_N, - Body::Cancel() => TYPE_CANCEL, - Body::Payload(_) => TYPE_PAYLOAD, - Body::Error(_) => TYPE_ERROR, - Body::MetadataPush(_) => TYPE_METADATA_PUSH, - Body::Resume(_) => TYPE_RESUME, - Body::ResumeOK(_) => TYPE_RESUME_OK, - } + match body { + Body::Setup(_) => TYPE_SETUP, + Body::Lease(_) => TYPE_LEASE, + Body::Keepalive(_) => TYPE_KEEPALIVE, + Body::RequestResponse(_) => TYPE_REQUEST_RESPONSE, + Body::RequestFNF(_) => TYPE_REQUEST_FNF, + Body::RequestStream(_) => TYPE_REQUEST_STREAM, + Body::RequestChannel(_) => TYPE_REQUEST_CHANNEL, + Body::RequestN(_) => TYPE_REQUEST_N, + Body::Cancel() => TYPE_CANCEL, + Body::Payload(_) => TYPE_PAYLOAD, + Body::Error(_) => TYPE_ERROR, + Body::MetadataPush(_) => TYPE_METADATA_PUSH, + Body::Resume(_) => TYPE_RESUME, + Body::ResumeOK(_) => TYPE_RESUME_OK, + } } diff --git a/src/frame/payload.rs b/src/frame/payload.rs index 4c6e932..c6ff532 100644 --- a/src/frame/payload.rs +++ b/src/frame/payload.rs @@ -4,76 +4,76 @@ use bytes::{BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct Payload { - metadata: Option, - data: Option, + metadata: Option, + data: Option, } pub struct PayloadBuilder { - stream_id: u32, - flag: u16, - value: Payload, + stream_id: u32, + flag: u16, + value: Payload, } impl PayloadBuilder { - fn new(stream_id: u32, flag: u16) -> PayloadBuilder { - PayloadBuilder { - stream_id, - flag, - value: Payload { - metadata: None, - data: None, - }, + fn new(stream_id: u32, flag: u16) -> PayloadBuilder { + PayloadBuilder { + stream_id, + flag, + value: Payload { + metadata: None, + data: None, + }, + } } - } - pub fn set_data(mut self, data: Bytes) -> Self { - self.value.data = Some(data); - self - } + pub fn set_data(mut self, data: Bytes) -> Self { + self.value.data = Some(data); + self + } - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.value.metadata = Some(metadata); - self.flag |= FLAG_METADATA; - self - } + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.value.metadata = Some(metadata); + self.flag |= FLAG_METADATA; + self + } - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::Payload(self.value), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::Payload(self.value), self.flag) + } } impl Payload { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let (m, d) = PayloadSupport::read(flag, bf); - Ok(Payload { - metadata: m, - data: d, - }) - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let (m, d) = PayloadSupport::read(flag, bf); + Ok(Payload { + metadata: m, + data: d, + }) + } - pub fn builder(stream_id: u32, flag: u16) -> PayloadBuilder { - PayloadBuilder::new(stream_id, flag) - } + pub fn builder(stream_id: u32, flag: u16) -> PayloadBuilder { + PayloadBuilder::new(stream_id, flag) + } - pub fn get_metadata(&self) -> &Option { - &self.metadata - } + pub fn get_metadata(&self) -> &Option { + &self.metadata + } - pub fn get_data(&self) -> &Option { - &self.data - } + pub fn get_data(&self) -> &Option { + &self.data + } - pub fn split(self) -> (Option, Option) { - (self.data, self.metadata) - } + pub fn split(self) -> (Option, Option) { + (self.data, self.metadata) + } } impl Writeable for Payload { - fn write_to(&self, bf: &mut BytesMut) { - PayloadSupport::write(bf, self.get_metadata(), self.get_data()); - } + fn write_to(&self, bf: &mut BytesMut) { + PayloadSupport::write(bf, self.get_metadata(), self.get_data()); + } - fn len(&self) -> usize { - PayloadSupport::len(self.get_metadata(), self.get_data()) - } + fn len(&self) -> usize { + PayloadSupport::len(self.get_metadata(), self.get_data()) + } } diff --git a/src/frame/request_channel.rs b/src/frame/request_channel.rs index 99686bf..5faf5cc 100644 --- a/src/frame/request_channel.rs +++ b/src/frame/request_channel.rs @@ -4,89 +4,89 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct RequestChannel { - initial_request_n: u32, - metadata: Option, - data: Option, + initial_request_n: u32, + metadata: Option, + data: Option, } pub struct RequestChannelBuilder { - stream_id: u32, - flag: u16, - value: RequestChannel, + stream_id: u32, + flag: u16, + value: RequestChannel, } impl RequestChannelBuilder { - pub fn new(stream_id: u32, flag: u16) -> RequestChannelBuilder { - RequestChannelBuilder { - stream_id, - flag, - value: RequestChannel { - initial_request_n: REQUEST_MAX, - metadata: None, - data: None, - }, + pub fn new(stream_id: u32, flag: u16) -> RequestChannelBuilder { + RequestChannelBuilder { + stream_id, + flag, + value: RequestChannel { + initial_request_n: REQUEST_MAX, + metadata: None, + data: None, + }, + } } - } - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::RequestChannel(self.value), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::RequestChannel(self.value), self.flag) + } - pub fn set_initial_request_n(mut self, n: u32) -> Self { - self.value.initial_request_n = n; - self - } + pub fn set_initial_request_n(mut self, n: u32) -> Self { + self.value.initial_request_n = n; + self + } - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.value.metadata = Some(metadata); - self.flag |= FLAG_METADATA; - self - } + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.value.metadata = Some(metadata); + self.flag |= FLAG_METADATA; + self + } - pub fn set_data(mut self, data: Bytes) -> Self { - self.value.data = Some(data); - self - } + pub fn set_data(mut self, data: Bytes) -> Self { + self.value.data = Some(data); + self + } } impl RequestChannel { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let n = bf.get_u32(); - let (m, d) = PayloadSupport::read(flag, bf); - Ok(RequestChannel { - initial_request_n: n, - metadata: m, - data: d, - }) - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let n = bf.get_u32(); + let (m, d) = PayloadSupport::read(flag, bf); + Ok(RequestChannel { + initial_request_n: n, + metadata: m, + data: d, + }) + } - pub fn builder(stream_id: u32, flag: u16) -> RequestChannelBuilder { - RequestChannelBuilder::new(stream_id, flag) - } + pub fn builder(stream_id: u32, flag: u16) -> RequestChannelBuilder { + RequestChannelBuilder::new(stream_id, flag) + } - pub fn get_initial_request_n(&self) -> u32 { - self.initial_request_n - } + pub fn get_initial_request_n(&self) -> u32 { + self.initial_request_n + } - pub fn get_metadata(&self) -> &Option { - &self.metadata - } - pub fn get_data(&self) -> &Option { - &self.data - } + pub fn get_metadata(&self) -> &Option { + &self.metadata + } + pub fn get_data(&self) -> &Option { + &self.data + } - pub fn split(self) -> (Option, Option) { - (self.data, self.metadata) - } + pub fn split(self) -> (Option, Option) { + (self.data, self.metadata) + } } impl Writeable for RequestChannel { - fn write_to(&self, bf: &mut BytesMut) { - bf.put_u32(self.initial_request_n); - PayloadSupport::write(bf, self.get_metadata(), self.get_data()); - } + fn write_to(&self, bf: &mut BytesMut) { + bf.put_u32(self.initial_request_n); + PayloadSupport::write(bf, self.get_metadata(), self.get_data()); + } - fn len(&self) -> usize { - 4 + PayloadSupport::len(self.get_metadata(), self.get_data()) - } + fn len(&self) -> usize { + 4 + PayloadSupport::len(self.get_metadata(), self.get_data()) + } } diff --git a/src/frame/request_fnf.rs b/src/frame/request_fnf.rs index 7719d92..d399860 100644 --- a/src/frame/request_fnf.rs +++ b/src/frame/request_fnf.rs @@ -4,76 +4,76 @@ use bytes::{BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct RequestFNF { - metadata: Option, - data: Option, + metadata: Option, + data: Option, } pub struct RequestFNFBuilder { - stream_id: u32, - flag: u16, - value: RequestFNF, + stream_id: u32, + flag: u16, + value: RequestFNF, } impl RequestFNFBuilder { - fn new(stream_id: u32, flag: u16) -> RequestFNFBuilder { - RequestFNFBuilder { - stream_id, - flag, - value: RequestFNF { - metadata: None, - data: None, - }, + fn new(stream_id: u32, flag: u16) -> RequestFNFBuilder { + RequestFNFBuilder { + stream_id, + flag, + value: RequestFNF { + metadata: None, + data: None, + }, + } } - } - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::RequestFNF(self.value), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::RequestFNF(self.value), self.flag) + } - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.value.metadata = Some(metadata); - self.flag |= FLAG_METADATA; - self - } + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.value.metadata = Some(metadata); + self.flag |= FLAG_METADATA; + self + } - pub fn set_data(mut self, data: Bytes) -> Self { - self.value.data = Some(data); - self - } + pub fn set_data(mut self, data: Bytes) -> Self { + self.value.data = Some(data); + self + } } impl RequestFNF { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let (m, d) = PayloadSupport::read(flag, bf); - Ok(RequestFNF { - metadata: m, - data: d, - }) - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let (m, d) = PayloadSupport::read(flag, bf); + Ok(RequestFNF { + metadata: m, + data: d, + }) + } - pub fn builder(stream_id: u32, flag: u16) -> RequestFNFBuilder { - RequestFNFBuilder::new(stream_id, flag) - } + pub fn builder(stream_id: u32, flag: u16) -> RequestFNFBuilder { + RequestFNFBuilder::new(stream_id, flag) + } - pub fn get_metadata(&self) -> &Option { - &self.metadata - } + pub fn get_metadata(&self) -> &Option { + &self.metadata + } - pub fn get_data(&self) -> &Option { - &self.data - } + pub fn get_data(&self) -> &Option { + &self.data + } - pub fn split(self) -> (Option, Option) { - (self.data, self.metadata) - } + pub fn split(self) -> (Option, Option) { + (self.data, self.metadata) + } } impl Writeable for RequestFNF { - fn write_to(&self, bf: &mut BytesMut) { - PayloadSupport::write(bf, self.get_metadata(), self.get_data()); - } + fn write_to(&self, bf: &mut BytesMut) { + PayloadSupport::write(bf, self.get_metadata(), self.get_data()); + } - fn len(&self) -> usize { - PayloadSupport::len(self.get_metadata(), self.get_data()) - } + fn len(&self) -> usize { + PayloadSupport::len(self.get_metadata(), self.get_data()) + } } diff --git a/src/frame/request_n.rs b/src/frame/request_n.rs index 2794f25..d28aeb4 100644 --- a/src/frame/request_n.rs +++ b/src/frame/request_n.rs @@ -4,55 +4,55 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct RequestN { - n: u32, + n: u32, } pub struct RequestNBuilder { - stream_id: u32, - flag: u16, - value: RequestN, + stream_id: u32, + flag: u16, + value: RequestN, } impl RequestNBuilder { - fn new(stream_id: u32, flag: u16) -> RequestNBuilder { - RequestNBuilder { - stream_id, - flag, - value: RequestN { n: REQUEST_MAX }, - } - } - - pub fn set_n(mut self, n: u32) -> Self { - self.value.n = n; - self - } - - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::RequestN(self.value), self.flag) - } + fn new(stream_id: u32, flag: u16) -> RequestNBuilder { + RequestNBuilder { + stream_id, + flag, + value: RequestN { n: REQUEST_MAX }, + } + } + + pub fn set_n(mut self, n: u32) -> Self { + self.value.n = n; + self + } + + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::RequestN(self.value), self.flag) + } } impl RequestN { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let n = bf.get_u32(); - Ok(RequestN { n }) - } - - pub fn builder(stream_id: u32, flag: u16) -> RequestNBuilder { - RequestNBuilder::new(stream_id, flag) - } - - pub fn get_n(&self) -> u32 { - self.n - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let n = bf.get_u32(); + Ok(RequestN { n }) + } + + pub fn builder(stream_id: u32, flag: u16) -> RequestNBuilder { + RequestNBuilder::new(stream_id, flag) + } + + pub fn get_n(&self) -> u32 { + self.n + } } impl Writeable for RequestN { - fn write_to(&self, bf: &mut BytesMut) { - bf.put_u32(self.get_n()) - } + fn write_to(&self, bf: &mut BytesMut) { + bf.put_u32(self.get_n()) + } - fn len(&self) -> usize { - 4 - } + fn len(&self) -> usize { + 4 + } } diff --git a/src/frame/request_response.rs b/src/frame/request_response.rs index a9418bf..d41024a 100644 --- a/src/frame/request_response.rs +++ b/src/frame/request_response.rs @@ -4,76 +4,76 @@ use bytes::{BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct RequestResponse { - metadata: Option, - data: Option, + metadata: Option, + data: Option, } pub struct RequestResponseBuilder { - stream_id: u32, - flag: u16, - value: RequestResponse, + stream_id: u32, + flag: u16, + value: RequestResponse, } impl RequestResponseBuilder { - fn new(stream_id: u32, flag: u16) -> RequestResponseBuilder { - RequestResponseBuilder { - stream_id, - flag, - value: RequestResponse { - metadata: None, - data: None, - }, + fn new(stream_id: u32, flag: u16) -> RequestResponseBuilder { + RequestResponseBuilder { + stream_id, + flag, + value: RequestResponse { + metadata: None, + data: None, + }, + } } - } - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.value.metadata = Some(metadata); - self.flag |= FLAG_METADATA; - self - } + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.value.metadata = Some(metadata); + self.flag |= FLAG_METADATA; + self + } - pub fn set_data(mut self, data: Bytes) -> Self { - self.value.data = Some(data); - self - } + pub fn set_data(mut self, data: Bytes) -> Self { + self.value.data = Some(data); + self + } - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::RequestResponse(self.value), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::RequestResponse(self.value), self.flag) + } } impl RequestResponse { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let (m, d) = PayloadSupport::read(flag, bf); - Ok(RequestResponse { - metadata: m, - data: d, - }) - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let (m, d) = PayloadSupport::read(flag, bf); + Ok(RequestResponse { + metadata: m, + data: d, + }) + } - pub fn builder(stream_id: u32, flag: u16) -> RequestResponseBuilder { - RequestResponseBuilder::new(stream_id, flag) - } + pub fn builder(stream_id: u32, flag: u16) -> RequestResponseBuilder { + RequestResponseBuilder::new(stream_id, flag) + } - pub fn get_metadata(&self) -> &Option { - &self.metadata - } + pub fn get_metadata(&self) -> &Option { + &self.metadata + } - pub fn get_data(&self) -> &Option { - &self.data - } + pub fn get_data(&self) -> &Option { + &self.data + } - pub fn split(self) -> (Option, Option) { - (self.data, self.metadata) - } + pub fn split(self) -> (Option, Option) { + (self.data, self.metadata) + } } impl Writeable for RequestResponse { - fn write_to(&self, bf: &mut BytesMut) { - PayloadSupport::write(bf, self.get_metadata(), self.get_data()) - } + fn write_to(&self, bf: &mut BytesMut) { + PayloadSupport::write(bf, self.get_metadata(), self.get_data()) + } - fn len(&self) -> usize { - PayloadSupport::len(self.get_metadata(), self.get_data()) - } + fn len(&self) -> usize { + PayloadSupport::len(self.get_metadata(), self.get_data()) + } } diff --git a/src/frame/request_stream.rs b/src/frame/request_stream.rs index aa8920d..33fa7a0 100644 --- a/src/frame/request_stream.rs +++ b/src/frame/request_stream.rs @@ -4,86 +4,86 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct RequestStream { - initial_request_n: u32, - metadata: Option, - data: Option, + initial_request_n: u32, + metadata: Option, + data: Option, } pub struct RequestStreamBuilder { - stream_id: u32, - flag: u16, - value: RequestStream, + stream_id: u32, + flag: u16, + value: RequestStream, } impl RequestStreamBuilder { - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::RequestStream(self.value), self.flag) - } + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::RequestStream(self.value), self.flag) + } - pub fn set_initial_request_n(mut self, n: u32) -> Self { - self.value.initial_request_n = n; - self - } + pub fn set_initial_request_n(mut self, n: u32) -> Self { + self.value.initial_request_n = n; + self + } - pub fn set_data(mut self, data: Bytes) -> Self { - self.value.data = Some(data); - self - } + pub fn set_data(mut self, data: Bytes) -> Self { + self.value.data = Some(data); + self + } - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.value.metadata = Some(metadata); - self.flag |= FLAG_METADATA; - self - } + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.value.metadata = Some(metadata); + self.flag |= FLAG_METADATA; + self + } } impl RequestStream { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let n = bf.get_u32(); - let (m, d) = PayloadSupport::read(flag, bf); - Ok(RequestStream { - initial_request_n: n, - metadata: m, - data: d, - }) - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let n = bf.get_u32(); + let (m, d) = PayloadSupport::read(flag, bf); + Ok(RequestStream { + initial_request_n: n, + metadata: m, + data: d, + }) + } - pub fn builder(stream_id: u32, flag: u16) -> RequestStreamBuilder { - RequestStreamBuilder { - stream_id, - flag, - value: RequestStream { - initial_request_n: REQUEST_MAX, - metadata: None, - data: None, - }, + pub fn builder(stream_id: u32, flag: u16) -> RequestStreamBuilder { + RequestStreamBuilder { + stream_id, + flag, + value: RequestStream { + initial_request_n: REQUEST_MAX, + metadata: None, + data: None, + }, + } } - } - pub fn get_initial_request_n(&self) -> u32 { - self.initial_request_n - } + pub fn get_initial_request_n(&self) -> u32 { + self.initial_request_n + } - pub fn get_metadata(&self) -> &Option { - &self.metadata - } + pub fn get_metadata(&self) -> &Option { + &self.metadata + } - pub fn get_data(&self) -> &Option { - &self.data - } + pub fn get_data(&self) -> &Option { + &self.data + } - pub fn split(self) -> (Option, Option) { - (self.data, self.metadata) - } + pub fn split(self) -> (Option, Option) { + (self.data, self.metadata) + } } impl Writeable for RequestStream { - fn write_to(&self, bf: &mut BytesMut) { - bf.put_u32(self.initial_request_n); - PayloadSupport::write(bf, self.get_metadata(), self.get_data()) - } + fn write_to(&self, bf: &mut BytesMut) { + bf.put_u32(self.initial_request_n); + PayloadSupport::write(bf, self.get_metadata(), self.get_data()) + } - fn len(&self) -> usize { - 4 + PayloadSupport::len(self.get_metadata(), self.get_data()) - } + fn len(&self) -> usize { + 4 + PayloadSupport::len(self.get_metadata(), self.get_data()) + } } diff --git a/src/frame/resume.rs b/src/frame/resume.rs index 7cf558b..efb9bbf 100644 --- a/src/frame/resume.rs +++ b/src/frame/resume.rs @@ -4,117 +4,117 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct Resume { - version: Version, - token: Option, - last_received_server_position: u64, - first_available_client_position: u64, + version: Version, + token: Option, + last_received_server_position: u64, + first_available_client_position: u64, } pub struct ResumeBuilder { - stream_id: u32, - flag: u16, - inner: Resume, + stream_id: u32, + flag: u16, + inner: Resume, } impl Resume { - fn new() -> Resume { - Resume { - version: Version::default(), - token: None, - last_received_server_position: 0, - first_available_client_position: 0, + fn new() -> Resume { + Resume { + version: Version::default(), + token: None, + last_received_server_position: 0, + first_available_client_position: 0, + } + } + + pub fn decode(flag: u16, b: &mut BytesMut) -> RSocketResult { + let major = b.get_u16(); + let minor = b.get_u16(); + let token_size = b.get_u16(); + let token = if token_size > 0 { + Some(b.split_to(token_size as usize).to_bytes()) + } else { + None + }; + let p1 = b.get_u64(); + let p2 = b.get_u64(); + Ok(Resume { + version: Version::new(major, minor), + token, + last_received_server_position: p1, + first_available_client_position: p2, + }) + } + + pub fn builder(stream_id: u32, flag: u16) -> ResumeBuilder { + ResumeBuilder::new(stream_id, flag) + } + + pub fn get_version(&self) -> Version { + self.version + } + + pub fn get_token(&self) -> &Option { + &self.token + } + + pub fn get_last_received_server_position(&self) -> u64 { + self.last_received_server_position + } + + pub fn get_first_available_client_position(&self) -> u64 { + self.first_available_client_position } - } - - pub fn decode(flag: u16, b: &mut BytesMut) -> RSocketResult { - let major = b.get_u16(); - let minor = b.get_u16(); - let token_size = b.get_u16(); - let token = if token_size > 0 { - Some(b.split_to(token_size as usize).to_bytes()) - } else { - None - }; - let p1 = b.get_u64(); - let p2 = b.get_u64(); - Ok(Resume { - version: Version::new(major, minor), - token, - last_received_server_position: p1, - first_available_client_position: p2, - }) - } - - pub fn builder(stream_id: u32, flag: u16) -> ResumeBuilder { - ResumeBuilder::new(stream_id, flag) - } - - pub fn get_version(&self) -> Version { - self.version - } - - pub fn get_token(&self) -> &Option { - &self.token - } - - pub fn get_last_received_server_position(&self) -> u64 { - self.last_received_server_position - } - - pub fn get_first_available_client_position(&self) -> u64 { - self.first_available_client_position - } } impl ResumeBuilder { - fn new(stream_id: u32, flag: u16) -> ResumeBuilder { - ResumeBuilder { - stream_id, - flag, - inner: Resume::new(), + fn new(stream_id: u32, flag: u16) -> ResumeBuilder { + ResumeBuilder { + stream_id, + flag, + inner: Resume::new(), + } + } + + pub fn set_token(mut self, token: Bytes) -> Self { + self.inner.token = Some(token); + self + } + + pub fn set_last_received_server_position(mut self, position: u64) -> Self { + self.inner.last_received_server_position = position; + self } - } - - pub fn set_token(mut self, token: Bytes) -> Self { - self.inner.token = Some(token); - self - } - - pub fn set_last_received_server_position(mut self, position: u64) -> Self { - self.inner.last_received_server_position = position; - self - } - - pub fn set_first_available_client_position(mut self, position: u64) -> Self { - self.inner.first_available_client_position = position; - self - } - - pub fn build(self) -> Frame { - Frame { - stream_id: self.stream_id, - flag: self.flag, - body: Body::Resume(self.inner), + + pub fn set_first_available_client_position(mut self, position: u64) -> Self { + self.inner.first_available_client_position = position; + self + } + + pub fn build(self) -> Frame { + Frame { + stream_id: self.stream_id, + flag: self.flag, + body: Body::Resume(self.inner), + } } - } } impl Writeable for Resume { - fn write_to(&self, bf: &mut BytesMut) { - self.version.write_to(bf); - if let Some(b) = self.get_token() { - bf.put_u16(b.len() as u16); - bf.put(b.bytes()); + fn write_to(&self, bf: &mut BytesMut) { + self.version.write_to(bf); + if let Some(b) = self.get_token() { + bf.put_u16(b.len() as u16); + bf.put(b.bytes()); + } + bf.put_u64(self.get_last_received_server_position()); + bf.put_u64(self.get_first_available_client_position()); } - bf.put_u64(self.get_last_received_server_position()); - bf.put_u64(self.get_first_available_client_position()); - } - - fn len(&self) -> usize { - let mut size: usize = 22; - if let Some(b) = self.get_token() { - size += b.len(); + + fn len(&self) -> usize { + let mut size: usize = 22; + if let Some(b) = self.get_token() { + size += b.len(); + } + size } - size - } } diff --git a/src/frame/resume_ok.rs b/src/frame/resume_ok.rs index 5c20b7a..29068c0 100644 --- a/src/frame/resume_ok.rs +++ b/src/frame/resume_ok.rs @@ -4,54 +4,54 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, PartialEq)] pub struct ResumeOK { - position: u64, + position: u64, } pub struct ResumeOKBuilder { - stream_id: u32, - flag: u16, - value: ResumeOK, + stream_id: u32, + flag: u16, + value: ResumeOK, } impl ResumeOKBuilder { - fn new(stream_id: u32, flag: u16) -> ResumeOKBuilder { - ResumeOKBuilder { - stream_id, - flag, - value: ResumeOK { position: 0 }, - } - } - pub fn set_position(mut self, position: u64) -> Self { - self.value.position = position; - self - } - - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::ResumeOK(self.value), self.flag) - } + fn new(stream_id: u32, flag: u16) -> ResumeOKBuilder { + ResumeOKBuilder { + stream_id, + flag, + value: ResumeOK { position: 0 }, + } + } + pub fn set_position(mut self, position: u64) -> Self { + self.value.position = position; + self + } + + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::ResumeOK(self.value), self.flag) + } } impl ResumeOK { - pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { - let position = bf.get_u64(); - Ok(ResumeOK { position }) - } - - pub fn builder(stream_id: u32, flag: u16) -> ResumeOKBuilder { - ResumeOKBuilder::new(stream_id, flag) - } - - pub fn get_position(&self) -> u64 { - self.position - } + pub fn decode(flag: u16, bf: &mut BytesMut) -> RSocketResult { + let position = bf.get_u64(); + Ok(ResumeOK { position }) + } + + pub fn builder(stream_id: u32, flag: u16) -> ResumeOKBuilder { + ResumeOKBuilder::new(stream_id, flag) + } + + pub fn get_position(&self) -> u64 { + self.position + } } impl Writeable for ResumeOK { - fn write_to(&self, bf: &mut BytesMut) { - bf.put_u64(self.get_position()) - } + fn write_to(&self, bf: &mut BytesMut) { + bf.put_u64(self.get_position()) + } - fn len(&self) -> usize { - 8 - } + fn len(&self) -> usize { + 8 + } } diff --git a/src/frame/setup.rs b/src/frame/setup.rs index 3086958..dc718e8 100644 --- a/src/frame/setup.rs +++ b/src/frame/setup.rs @@ -6,190 +6,190 @@ use std::time::Duration; #[derive(Debug, PartialEq)] pub struct Setup { - version: Version, - keepalive: u32, - lifetime: u32, - token: Option, - mime_metadata: String, - mime_data: String, - metadata: Option, - data: Option, + version: Version, + keepalive: u32, + lifetime: u32, + token: Option, + mime_metadata: String, + mime_data: String, + metadata: Option, + data: Option, } impl Writeable for Setup { - fn len(&self) -> usize { - let mut n: usize = 12; - n += match &self.token { - Some(v) => 2 + v.len(), - None => 0, - }; - n += 2 + self.mime_metadata.len() + self.mime_data.len(); - n += PayloadSupport::len(&self.metadata, &self.data); - n - } - - fn write_to(&self, bf: &mut BytesMut) { - self.version.write_to(bf); - bf.put_u32(self.keepalive); - bf.put_u32(self.lifetime); - if let Some(b) = &self.token { - bf.put_u16(b.len() as u16); - bf.put(b.bytes()); - } - // TODO: remove string clone - bf.put_u8(self.mime_metadata.len() as u8); - bf.put(Bytes::from(self.mime_metadata.clone())); - bf.put_u8(self.mime_data.len() as u8); - bf.put(Bytes::from(self.mime_data.clone())); - PayloadSupport::write(bf, self.get_metadata(), self.get_data()); - } + fn len(&self) -> usize { + let mut n: usize = 12; + n += match &self.token { + Some(v) => 2 + v.len(), + None => 0, + }; + n += 2 + self.mime_metadata.len() + self.mime_data.len(); + n += PayloadSupport::len(&self.metadata, &self.data); + n + } + + fn write_to(&self, bf: &mut BytesMut) { + self.version.write_to(bf); + bf.put_u32(self.keepalive); + bf.put_u32(self.lifetime); + if let Some(b) = &self.token { + bf.put_u16(b.len() as u16); + bf.put(b.bytes()); + } + // TODO: remove string clone + bf.put_u8(self.mime_metadata.len() as u8); + bf.put(Bytes::from(self.mime_metadata.clone())); + bf.put_u8(self.mime_data.len() as u8); + bf.put(Bytes::from(self.mime_data.clone())); + PayloadSupport::write(bf, self.get_metadata(), self.get_data()); + } } impl Setup { - pub fn decode(flag: u16, b: &mut BytesMut) -> RSocketResult { - let major = b.get_u16(); - let minor = b.get_u16(); - let keepalive = b.get_u32(); - let lifetime = b.get_u32(); - let token: Option = if flag & FLAG_RESUME != 0 { - let l = b.get_u16(); - Some(b.split_to(l as usize).to_bytes()) - } else { - None - }; - let mut len_mime: usize = b[0] as usize; - b.advance(1); - let mime_metadata = b.split_to(len_mime); - len_mime = b[0] as usize; - b.advance(1); - let mime_data = b.split_to(len_mime); - let (metadata, data) = PayloadSupport::read(flag, b); - Ok(Setup { - version: Version::new(major, minor), - keepalive, - lifetime, - token, - mime_metadata: String::from_utf8(mime_metadata.to_vec()).unwrap(), - mime_data: String::from_utf8(mime_data.to_vec()).unwrap(), - metadata, - data, - }) - } - - pub fn builder(stream_id: u32, flag: u16) -> SetupBuilder { - SetupBuilder::new(stream_id, flag) - } - - pub fn get_version(&self) -> Version { - self.version - } - - pub fn get_keepalive(&self) -> Duration { - Duration::from_millis(u64::from(self.keepalive)) - } - - pub fn get_lifetime(&self) -> Duration { - Duration::from_millis(u64::from(self.lifetime)) - } - - pub fn get_token(&self) -> Option { - self.token.clone() - } - - pub fn get_mime_metadata(&self) -> &String { - &self.mime_metadata - } - - pub fn get_mime_data(&self) -> &String { - &self.mime_data - } - - pub fn get_metadata(&self) -> &Option { - &self.metadata - } - - pub fn get_data(&self) -> &Option { - &self.data - } - - pub fn split(self) -> (Option, Option) { - (self.data, self.metadata) - } + pub fn decode(flag: u16, b: &mut BytesMut) -> RSocketResult { + let major = b.get_u16(); + let minor = b.get_u16(); + let keepalive = b.get_u32(); + let lifetime = b.get_u32(); + let token: Option = if flag & FLAG_RESUME != 0 { + let l = b.get_u16(); + Some(b.split_to(l as usize).to_bytes()) + } else { + None + }; + let mut len_mime: usize = b[0] as usize; + b.advance(1); + let mime_metadata = b.split_to(len_mime); + len_mime = b[0] as usize; + b.advance(1); + let mime_data = b.split_to(len_mime); + let (metadata, data) = PayloadSupport::read(flag, b); + Ok(Setup { + version: Version::new(major, minor), + keepalive, + lifetime, + token, + mime_metadata: String::from_utf8(mime_metadata.to_vec()).unwrap(), + mime_data: String::from_utf8(mime_data.to_vec()).unwrap(), + metadata, + data, + }) + } + + pub fn builder(stream_id: u32, flag: u16) -> SetupBuilder { + SetupBuilder::new(stream_id, flag) + } + + pub fn get_version(&self) -> Version { + self.version + } + + pub fn get_keepalive(&self) -> Duration { + Duration::from_millis(u64::from(self.keepalive)) + } + + pub fn get_lifetime(&self) -> Duration { + Duration::from_millis(u64::from(self.lifetime)) + } + + pub fn get_token(&self) -> Option { + self.token.clone() + } + + pub fn get_mime_metadata(&self) -> &String { + &self.mime_metadata + } + + pub fn get_mime_data(&self) -> &String { + &self.mime_data + } + + pub fn get_metadata(&self) -> &Option { + &self.metadata + } + + pub fn get_data(&self) -> &Option { + &self.data + } + + pub fn split(self) -> (Option, Option) { + (self.data, self.metadata) + } } pub struct SetupBuilder { - stream_id: u32, - flag: u16, - value: Setup, + stream_id: u32, + flag: u16, + value: Setup, } impl SetupBuilder { - fn new(stream_id: u32, flag: u16) -> SetupBuilder { - SetupBuilder { - stream_id, - flag, - value: Setup { - version: Version::default(), - keepalive: 30_000, - lifetime: 90_000, - token: None, - mime_metadata: String::from(APPLICATION_BINARY), - mime_data: String::from(APPLICATION_BINARY), - metadata: None, - data: None, - }, - } - } - - pub fn build(self) -> Frame { - Frame::new(self.stream_id, Body::Setup(self.value), self.flag) - } - - pub fn set_data(mut self, bs: Bytes) -> Self { - self.value.data = Some(bs); - self - } - - pub fn set_metadata(mut self, bs: Bytes) -> Self { - self.flag |= FLAG_METADATA; - self.value.metadata = Some(bs); - self - } - - pub fn set_version(mut self, major: u16, minor: u16) -> Self { - self.value.version = Version::new(major, minor); - self - } - - pub fn set_keepalive(mut self, duration: Duration) -> Self { - self.value.keepalive = duration.as_millis() as u32; - self - } - - pub fn set_lifetime(mut self, duration: Duration) -> Self { - self.value.lifetime = duration.as_millis() as u32; - self - } - - pub fn set_token(mut self, token: Bytes) -> Self { - self.value.token = Some(token); - self.flag |= FLAG_RESUME; - self - } - - pub fn set_mime_metadata(mut self, mime: &str) -> Self { - if mime.len() > 256 { - panic!("maximum mime length is 256"); - } - self.value.mime_metadata = String::from(mime); - self - } - - pub fn set_mime_data(mut self, mime: &str) -> Self { - if mime.len() > 256 { - panic!("maximum mime length is 256"); - } - self.value.mime_data = String::from(mime); - self - } + fn new(stream_id: u32, flag: u16) -> SetupBuilder { + SetupBuilder { + stream_id, + flag, + value: Setup { + version: Version::default(), + keepalive: 30_000, + lifetime: 90_000, + token: None, + mime_metadata: String::from(APPLICATION_BINARY), + mime_data: String::from(APPLICATION_BINARY), + metadata: None, + data: None, + }, + } + } + + pub fn build(self) -> Frame { + Frame::new(self.stream_id, Body::Setup(self.value), self.flag) + } + + pub fn set_data(mut self, bs: Bytes) -> Self { + self.value.data = Some(bs); + self + } + + pub fn set_metadata(mut self, bs: Bytes) -> Self { + self.flag |= FLAG_METADATA; + self.value.metadata = Some(bs); + self + } + + pub fn set_version(mut self, major: u16, minor: u16) -> Self { + self.value.version = Version::new(major, minor); + self + } + + pub fn set_keepalive(mut self, duration: Duration) -> Self { + self.value.keepalive = duration.as_millis() as u32; + self + } + + pub fn set_lifetime(mut self, duration: Duration) -> Self { + self.value.lifetime = duration.as_millis() as u32; + self + } + + pub fn set_token(mut self, token: Bytes) -> Self { + self.value.token = Some(token); + self.flag |= FLAG_RESUME; + self + } + + pub fn set_mime_metadata(mut self, mime: &str) -> Self { + if mime.len() > 256 { + panic!("maximum mime length is 256"); + } + self.value.mime_metadata = String::from(mime); + self + } + + pub fn set_mime_data(mut self, mime: &str) -> Self { + if mime.len() > 256 { + panic!("maximum mime length is 256"); + } + self.value.mime_data = String::from(mime); + self + } } diff --git a/src/frame/utils.rs b/src/frame/utils.rs index 17fe671..fe2d876 100644 --- a/src/frame/utils.rs +++ b/src/frame/utils.rs @@ -4,73 +4,73 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; pub struct U24; impl U24 { - pub fn max() -> usize { - 0x00FF_FFFF - } + pub fn max() -> usize { + 0x00FF_FFFF + } - pub fn write(n: u32, bf: &mut BytesMut) { - bf.put_u8((0xFF & (n >> 16)) as u8); - bf.put_u8((0xFF & (n >> 8)) as u8); - bf.put_u8((0xFF & n) as u8); - } + pub fn write(n: u32, bf: &mut BytesMut) { + bf.put_u8((0xFF & (n >> 16)) as u8); + bf.put_u8((0xFF & (n >> 8)) as u8); + bf.put_u8((0xFF & n) as u8); + } - pub fn read(bf: &mut BytesMut) -> u32 { - let mut n: u32 = 0; - n += u32::from(bf[0]) << 16; - n += u32::from(bf[1]) << 8; - n += u32::from(bf[2]); - n - } + pub fn read(bf: &mut BytesMut) -> u32 { + let mut n: u32 = 0; + n += u32::from(bf[0]) << 16; + n += u32::from(bf[1]) << 8; + n += u32::from(bf[2]); + n + } - pub fn read_advance(bf: &mut BytesMut) -> u32 { - let mut n: u32 = 0; - let raw = bf.split_to(3); - n += u32::from(raw[0]) << 16; - n += u32::from(raw[1]) << 8; - n += u32::from(raw[2]); - n - } + pub fn read_advance(bf: &mut BytesMut) -> u32 { + let mut n: u32 = 0; + let raw = bf.split_to(3); + n += u32::from(raw[0]) << 16; + n += u32::from(raw[1]) << 8; + n += u32::from(raw[2]); + n + } } pub struct PayloadSupport {} impl PayloadSupport { - pub fn len(metadata: &Option, data: &Option) -> usize { - let a = match metadata { - Some(v) => 3 + v.len(), - None => 0, - }; - let b = match data { - Some(v) => v.len(), - None => 0, - }; - a + b - } - - // TODO: change to Result - pub fn read(flag: u16, bf: &mut BytesMut) -> (Option, Option) { - let m: Option = if flag & FLAG_METADATA != 0 { - let n = U24::read_advance(bf); - Some(bf.split_to(n as usize).to_bytes()) - } else { - None - }; - let d: Option = if bf.is_empty() { - None - } else { - Some(Bytes::from(bf.to_vec())) - }; - (m, d) - } + pub fn len(metadata: &Option, data: &Option) -> usize { + let a = match metadata { + Some(v) => 3 + v.len(), + None => 0, + }; + let b = match data { + Some(v) => v.len(), + None => 0, + }; + a + b + } - pub fn write(bf: &mut BytesMut, metadata: &Option, data: &Option) { - if let Some(v) = metadata { - let n = v.len() as u32; - U24::write(n, bf); - bf.put(v.bytes()); + // TODO: change to Result + pub fn read(flag: u16, bf: &mut BytesMut) -> (Option, Option) { + let m: Option = if flag & FLAG_METADATA != 0 { + let n = U24::read_advance(bf); + Some(bf.split_to(n as usize).to_bytes()) + } else { + None + }; + let d: Option = if bf.is_empty() { + None + } else { + Some(Bytes::from(bf.to_vec())) + }; + (m, d) } - if let Some(v) = data { - bf.put(v.bytes()) + + pub fn write(bf: &mut BytesMut, metadata: &Option, data: &Option) { + if let Some(v) = metadata { + let n = v.len() as u32; + U24::write(n, bf); + bf.put(v.bytes()); + } + if let Some(v) = data { + bf.put(v.bytes()) + } } - } } diff --git a/src/frame/version.rs b/src/frame/version.rs index 0c9df39..2fd918a 100644 --- a/src/frame/version.rs +++ b/src/frame/version.rs @@ -2,31 +2,31 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; #[derive(Debug, Copy, Clone, PartialEq)] pub struct Version { - major: u16, - minor: u16, + major: u16, + minor: u16, } impl Default for Version { - fn default() -> Version { - Version { major: 1, minor: 0 } - } + fn default() -> Version { + Version { major: 1, minor: 0 } + } } impl Version { - pub fn new(major: u16, minor: u16) -> Version { - Version { major, minor } - } + pub fn new(major: u16, minor: u16) -> Version { + Version { major, minor } + } - pub fn get_major(self) -> u16 { - self.major - } + pub fn get_major(self) -> u16 { + self.major + } - pub fn get_minor(self) -> u16 { - self.minor - } + pub fn get_minor(self) -> u16 { + self.minor + } - pub fn write_to(self, bf: &mut BytesMut) { - bf.put_u16(self.major); - bf.put_u16(self.minor); - } + pub fn write_to(self, bf: &mut BytesMut) { + bf.put_u16(self.major); + bf.put_u16(self.minor); + } } diff --git a/src/payload/default.rs b/src/payload/default.rs index bf342ab..e0626c5 100644 --- a/src/payload/default.rs +++ b/src/payload/default.rs @@ -3,134 +3,134 @@ use bytes::Bytes; #[derive(Debug, Clone)] pub struct Payload { - m: Option, - d: Option, + m: Option, + d: Option, } #[derive(Debug)] pub struct PayloadBuilder { - value: Payload, + value: Payload, } impl PayloadBuilder { - fn new() -> PayloadBuilder { - PayloadBuilder { - value: Payload { m: None, d: None }, + fn new() -> PayloadBuilder { + PayloadBuilder { + value: Payload { m: None, d: None }, + } } - } - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.value.m = Some(metadata); - self - } + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.value.m = Some(metadata); + self + } - pub fn set_metadata_utf8(self, metadata: &str) -> Self { - self.set_metadata(Bytes::from(String::from(metadata))) - } + pub fn set_metadata_utf8(self, metadata: &str) -> Self { + self.set_metadata(Bytes::from(String::from(metadata))) + } - pub fn set_data(mut self, data: Bytes) -> Self { - self.value.d = Some(data); - self - } + pub fn set_data(mut self, data: Bytes) -> Self { + self.value.d = Some(data); + self + } - pub fn set_data_utf8(self, data: &str) -> Self { - self.set_data(Bytes::from(String::from(data))) - } + pub fn set_data_utf8(self, data: &str) -> Self { + self.set_data(Bytes::from(String::from(data))) + } - pub fn build(self) -> Payload { - self.value - } + pub fn build(self) -> Payload { + self.value + } } impl Payload { - pub fn builder() -> PayloadBuilder { - PayloadBuilder::new() - } + pub fn builder() -> PayloadBuilder { + PayloadBuilder::new() + } - pub fn metadata(&self) -> &Option { - &self.m - } + pub fn metadata(&self) -> &Option { + &self.m + } - pub fn data(&self) -> &Option { - &self.d - } + pub fn data(&self) -> &Option { + &self.d + } - pub fn split(self) -> (Option, Option) { - (self.d, self.m) - } + pub fn split(self) -> (Option, Option) { + (self.d, self.m) + } } impl From<&'static str> for Payload { - fn from(data: &'static str) -> Payload { - Payload { - d: Some(Bytes::from(data)), - m: None, + fn from(data: &'static str) -> Payload { + Payload { + d: Some(Bytes::from(data)), + m: None, + } } - } } impl From<(&'static str, &'static str)> for Payload { - fn from((data, metadata): (&'static str, &'static str)) -> Payload { - Payload { - d: Some(Bytes::from(data)), - m: Some(Bytes::from(metadata)), + fn from((data, metadata): (&'static str, &'static str)) -> Payload { + Payload { + d: Some(Bytes::from(data)), + m: Some(Bytes::from(metadata)), + } } - } } impl From<(Option, Option)> for Payload { - fn from((data, metadata): (Option, Option)) -> Payload { - let mut bu = Payload::builder(); - if let Some(b) = metadata { - bu = bu.set_metadata(b); + fn from((data, metadata): (Option, Option)) -> Payload { + let mut bu = Payload::builder(); + if let Some(b) = metadata { + bu = bu.set_metadata(b); + } + if let Some(b) = data { + bu = bu.set_data(b); + } + bu.build() } - if let Some(b) = data { - bu = bu.set_data(b); - } - bu.build() - } } impl From for Payload { - fn from(input: frame::Payload) -> Payload { - let d = input.get_data().clone(); - let m = input.get_metadata().clone(); - Payload::from((d, m)) - } + fn from(input: frame::Payload) -> Payload { + let d = input.get_data().clone(); + let m = input.get_metadata().clone(); + Payload::from((d, m)) + } } impl From for Payload { - fn from(input: frame::Setup) -> Payload { - Payload::from(input.split()) - } + fn from(input: frame::Setup) -> Payload { + Payload::from(input.split()) + } } impl From for Payload { - fn from(input: frame::RequestChannel) -> Payload { - Payload::from(input.split()) - } + fn from(input: frame::RequestChannel) -> Payload { + Payload::from(input.split()) + } } impl From for Payload { - fn from(input: frame::MetadataPush) -> Payload { - Payload::from(input.split()) - } + fn from(input: frame::MetadataPush) -> Payload { + Payload::from(input.split()) + } } impl From for Payload { - fn from(input: frame::RequestStream) -> Payload { - Payload::from(input.split()) - } + fn from(input: frame::RequestStream) -> Payload { + Payload::from(input.split()) + } } impl From for Payload { - fn from(input: frame::RequestFNF) -> Payload { - Payload::from(input.split()) - } + fn from(input: frame::RequestFNF) -> Payload { + Payload::from(input.split()) + } } impl From for Payload { - fn from(input: frame::RequestResponse) -> Payload { - Payload::from(input.split()) - } + fn from(input: frame::RequestResponse) -> Payload { + Payload::from(input.split()) + } } diff --git a/src/payload/setup.rs b/src/payload/setup.rs index 86c1b30..779643d 100644 --- a/src/payload/setup.rs +++ b/src/payload/setup.rs @@ -5,127 +5,127 @@ use std::time::Duration; #[derive(Debug)] pub struct SetupPayload { - m: Option, - d: Option, - keepalive: (Duration, Duration), - mime_m: Option, - mime_d: Option, + m: Option, + d: Option, + keepalive: (Duration, Duration), + mime_m: Option, + mime_d: Option, } #[derive(Debug)] pub struct SetupPayloadBuilder { - inner: SetupPayload, + inner: SetupPayload, } impl SetupPayload { - pub fn builder() -> SetupPayloadBuilder { - SetupPayloadBuilder::new() - } + pub fn builder() -> SetupPayloadBuilder { + SetupPayloadBuilder::new() + } } impl SetupPayloadBuilder { - fn new() -> SetupPayloadBuilder { - SetupPayloadBuilder { - inner: SetupPayload { - m: None, - d: None, - keepalive: (Duration::from_secs(20), Duration::from_secs(90)), - mime_m: Some(String::from(APPLICATION_BINARY)), - mime_d: Some(String::from(APPLICATION_BINARY)), - }, - } - } - - pub fn set_metadata(mut self, metadata: Bytes) -> Self { - self.inner.m = Some(metadata); - self - } - - pub fn set_metadata_utf8(self, metadata: &str) -> Self { - self.set_metadata(Bytes::from(String::from(metadata))) - } - - pub fn set_data(mut self, data: Bytes) -> Self { - self.inner.d = Some(data); - self - } - - pub fn set_data_utf8(self, data: &str) -> Self { - self.set_data(Bytes::from(String::from(data))) - } - - pub fn set_keepalive( - mut self, - tick_period: Duration, - ack_timeout: Duration, - missed_acks: u64, - ) -> Self { - let lifetime_mills = (ack_timeout.as_millis() as u64) * missed_acks; - self.inner.keepalive = (tick_period, Duration::from_millis(lifetime_mills)); - self - } - - pub fn set_data_mime_type(mut self, mime: &str) -> Self { - self.inner.mime_d = Some(String::from(mime)); - self - } - pub fn set_metadata_mime_type(mut self, mime: &str) -> Self { - self.inner.mime_m = Some(String::from(mime)); - self - } - - pub fn build(self) -> SetupPayload { - self.inner - } + fn new() -> SetupPayloadBuilder { + SetupPayloadBuilder { + inner: SetupPayload { + m: None, + d: None, + keepalive: (Duration::from_secs(20), Duration::from_secs(90)), + mime_m: Some(String::from(APPLICATION_BINARY)), + mime_d: Some(String::from(APPLICATION_BINARY)), + }, + } + } + + pub fn set_metadata(mut self, metadata: Bytes) -> Self { + self.inner.m = Some(metadata); + self + } + + pub fn set_metadata_utf8(self, metadata: &str) -> Self { + self.set_metadata(Bytes::from(String::from(metadata))) + } + + pub fn set_data(mut self, data: Bytes) -> Self { + self.inner.d = Some(data); + self + } + + pub fn set_data_utf8(self, data: &str) -> Self { + self.set_data(Bytes::from(String::from(data))) + } + + pub fn set_keepalive( + mut self, + tick_period: Duration, + ack_timeout: Duration, + missed_acks: u64, + ) -> Self { + let lifetime_mills = (ack_timeout.as_millis() as u64) * missed_acks; + self.inner.keepalive = (tick_period, Duration::from_millis(lifetime_mills)); + self + } + + pub fn set_data_mime_type(mut self, mime: &str) -> Self { + self.inner.mime_d = Some(String::from(mime)); + self + } + pub fn set_metadata_mime_type(mut self, mime: &str) -> Self { + self.inner.mime_m = Some(String::from(mime)); + self + } + + pub fn build(self) -> SetupPayload { + self.inner + } } impl SetupPayload { - pub fn metadata(&self) -> &Option { - &self.m - } + pub fn metadata(&self) -> &Option { + &self.m + } - pub fn data(&self) -> &Option { - &self.d - } + pub fn data(&self) -> &Option { + &self.d + } - pub fn split(self) -> (Option, Option) { - (self.d, self.m) - } + pub fn split(self) -> (Option, Option) { + (self.d, self.m) + } - pub fn keepalive_interval(&self) -> Duration { - self.keepalive.0 - } + pub fn keepalive_interval(&self) -> Duration { + self.keepalive.0 + } - pub fn keepalive_lifetime(&self) -> Duration { - self.keepalive.1 - } + pub fn keepalive_lifetime(&self) -> Duration { + self.keepalive.1 + } - pub fn metadata_mime_type(&self) -> &Option { - &self.mime_m - } + pub fn metadata_mime_type(&self) -> &Option { + &self.mime_m + } - pub fn data_mime_type(&self) -> &Option { - &self.mime_d - } + pub fn data_mime_type(&self) -> &Option { + &self.mime_d + } } impl From for SetupPayload { - fn from(input: Setup) -> SetupPayload { - let mut bu = SetupPayload::builder(); - // TODO: fill other properties. - bu = bu.set_data_mime_type(input.get_mime_data()); - bu = bu.set_metadata_mime_type(input.get_mime_metadata()); - // bu.set_data_mime_type(String::input.get_mime_data()); - let ka = (input.get_keepalive(), input.get_lifetime()); - let (d, m) = input.split(); - if let Some(b) = d { - bu = bu.set_data(b); - } - if let Some(b) = m { - bu = bu.set_metadata(b); - } - let mut pa = bu.build(); - pa.keepalive = ka; - pa - } + fn from(input: Setup) -> SetupPayload { + let mut bu = SetupPayload::builder(); + // TODO: fill other properties. + bu = bu.set_data_mime_type(input.get_mime_data()); + bu = bu.set_metadata_mime_type(input.get_mime_metadata()); + // bu.set_data_mime_type(String::input.get_mime_data()); + let ka = (input.get_keepalive(), input.get_lifetime()); + let (d, m) = input.split(); + if let Some(b) = d { + bu = bu.set_data(b); + } + if let Some(b) = m { + bu = bu.set_metadata(b); + } + let mut pa = bu.build(); + pa.keepalive = ka; + pa + } } diff --git a/src/transport/codec.rs b/src/transport/codec.rs index d4028b2..17a4ab4 100644 --- a/src/transport/codec.rs +++ b/src/transport/codec.rs @@ -7,36 +7,36 @@ use tokio_util::codec::{Decoder, Encoder}; pub struct RFrameCodec; impl Decoder for RFrameCodec { - type Item = Frame; - type Error = Error; + type Item = Frame; + type Error = Error; - fn decode(&mut self, buf: &mut BytesMut) -> Result, Self::Error> { - let actual = buf.len(); - if actual < 3 { - return Ok(None); + fn decode(&mut self, buf: &mut BytesMut) -> Result, Self::Error> { + let actual = buf.len(); + if actual < 3 { + return Ok(None); + } + let l = U24::read(buf) as usize; + if actual < 3 + l { + return Ok(None); + } + buf.advance(3); + let mut bb = buf.split_to(l); + match Frame::decode(&mut bb) { + Ok(v) => Ok(Some(v)), + Err(e) => Err(Error::from(ErrorKind::InvalidInput)), + } } - let l = U24::read(buf) as usize; - if actual < 3 + l { - return Ok(None); - } - buf.advance(3); - let mut bb = buf.split_to(l); - match Frame::decode(&mut bb) { - Ok(v) => Ok(Some(v)), - Err(e) => Err(Error::from(ErrorKind::InvalidInput)), - } - } } impl Encoder for RFrameCodec { - type Item = Frame; - type Error = Error; - fn encode(&mut self, item: Frame, buf: &mut BytesMut) -> Result<(), Self::Error> { - let sid = item.get_stream_id(); - let l = item.len(); - buf.reserve(3 + l); - U24::write(l as u32, buf); - item.write_to(buf); - Ok(()) - } + type Item = Frame; + type Error = Error; + fn encode(&mut self, item: Frame, buf: &mut BytesMut) -> Result<(), Self::Error> { + let sid = item.get_stream_id(); + let l = item.len(); + buf.reserve(3 + l); + U24::write(l as u32, buf); + item.write_to(buf); + Ok(()) + } } diff --git a/src/transport/spi.rs b/src/transport/spi.rs index 19a36b9..ac21a2e 100644 --- a/src/transport/spi.rs +++ b/src/transport/spi.rs @@ -6,16 +6,16 @@ pub type Tx = UnboundedSender; pub type Rx = UnboundedReceiver; pub struct Transport { - tx: UnboundedSender, - rx: UnboundedReceiver, + tx: UnboundedSender, + rx: UnboundedReceiver, } impl Transport { - pub fn new(tx: Tx, rx: Rx) -> Transport { - Transport { tx, rx } - } + pub fn new(tx: Tx, rx: Rx) -> Transport { + Transport { tx, rx } + } - pub fn split(self) -> (Tx, Rx) { - (self.tx, self.rx) - } + pub fn split(self) -> (Tx, Rx) { + (self.tx, self.rx) + } } diff --git a/src/transport/tcp.rs b/src/transport/tcp.rs index 97e8e38..5c218be 100644 --- a/src/transport/tcp.rs +++ b/src/transport/tcp.rs @@ -11,27 +11,27 @@ use tokio::sync::mpsc; use tokio_util::codec::{Decoder, Encoder, Framed, FramedParts, FramedRead, FramedWrite}; pub fn connect(addr: &SocketAddr) -> TcpStream { - let origin = StdTcpStream::connect(addr).unwrap(); - TcpStream::from_std(origin).unwrap() + let origin = StdTcpStream::connect(addr).unwrap(); + TcpStream::from_std(origin).unwrap() } pub async fn process(socket: TcpStream, mut inputs: Rx, outputs: Tx) { - let (mut writer, mut reader) = Framed::new(socket, RFrameCodec).split(); - tokio::spawn(async move { - // loop read - loop { - match reader.next().await { - Some(it) => outputs.send(it.unwrap()).unwrap(), - None => { - drop(outputs); - break; + let (mut writer, mut reader) = Framed::new(socket, RFrameCodec).split(); + tokio::spawn(async move { + // loop read + loop { + match reader.next().await { + Some(it) => outputs.send(it.unwrap()).unwrap(), + None => { + drop(outputs); + break; + } + } } - } + }); + // loop write + while let Some(it) = inputs.recv().await { + misc::debug_frame(true, &it); + writer.send(it).await.unwrap() } - }); - // loop write - while let Some(it) = inputs.recv().await { - misc::debug_frame(true, &it); - writer.send(it).await.unwrap() - } } diff --git a/src/x/client.rs b/src/x/client.rs index 51534a9..04e0705 100644 --- a/src/x/client.rs +++ b/src/x/client.rs @@ -11,132 +11,134 @@ use tokio::sync::mpsc; #[derive(Clone)] pub struct Client { - socket: DuplexSocket, + socket: DuplexSocket, } pub struct ClientBuilder { - uri: Option, - setup: SetupPayloadBuilder, - responder: Option Box>, + uri: Option, + setup: SetupPayloadBuilder, + responder: Option Box>, } impl Client { - fn new(socket: DuplexSocket) -> Client { - Client { socket } - } + fn new(socket: DuplexSocket) -> Client { + Client { socket } + } - pub fn builder() -> ClientBuilder { - ClientBuilder::new() - } + pub fn builder() -> ClientBuilder { + ClientBuilder::new() + } - pub fn close(self) { - self.socket.close(); - } + pub fn close(self) { + self.socket.close(); + } } impl ClientBuilder { - fn new() -> ClientBuilder { - ClientBuilder { - uri: None, - responder: None, - setup: SetupPayload::builder(), + fn new() -> ClientBuilder { + ClientBuilder { + uri: None, + responder: None, + setup: SetupPayload::builder(), + } } - } - - pub fn transport(mut self, uri: URI) -> Self { - self.uri = Some(uri); - self - } - pub fn setup(mut self, setup: Payload) -> Self { - let (d, m) = setup.split(); - if let Some(b) = d { - self.setup = self.setup.set_data(b); + pub fn transport(mut self, uri: URI) -> Self { + self.uri = Some(uri); + self } - if let Some(b) = m { - self.setup = self.setup.set_metadata(b); + + pub fn setup(mut self, setup: Payload) -> Self { + let (d, m) = setup.split(); + if let Some(b) = d { + self.setup = self.setup.set_data(b); + } + if let Some(b) = m { + self.setup = self.setup.set_metadata(b); + } + self } - self - } - pub fn keepalive( - mut self, - tick_period: Duration, - ack_timeout: Duration, - missed_acks: u64, - ) -> Self { - self.setup = self - .setup - .set_keepalive(tick_period, ack_timeout, missed_acks); - self - } + pub fn keepalive( + mut self, + tick_period: Duration, + ack_timeout: Duration, + missed_acks: u64, + ) -> Self { + self.setup = self + .setup + .set_keepalive(tick_period, ack_timeout, missed_acks); + self + } - pub fn mime_type(mut self, metadata_mime_type: &str, data_mime_type: &str) -> Self { - self = self.metadata_mime_type(metadata_mime_type); - self = self.data_mime_type(data_mime_type); - self - } + pub fn mime_type(mut self, metadata_mime_type: &str, data_mime_type: &str) -> Self { + self = self.metadata_mime_type(metadata_mime_type); + self = self.data_mime_type(data_mime_type); + self + } - pub fn data_mime_type(mut self, mime_type: &str) -> Self { - self.setup = self.setup.set_data_mime_type(mime_type); - self - } + pub fn data_mime_type(mut self, mime_type: &str) -> Self { + self.setup = self.setup.set_data_mime_type(mime_type); + self + } - pub fn metadata_mime_type(mut self, mime_type: &str) -> Self { - self.setup = self.setup.set_metadata_mime_type(mime_type); - self - } + pub fn metadata_mime_type(mut self, mime_type: &str) -> Self { + self.setup = self.setup.set_metadata_mime_type(mime_type); + self + } - pub fn acceptor(mut self, acceptor: fn() -> Box) -> Self { - self.responder = Some(acceptor); - self - } + pub fn acceptor(mut self, acceptor: fn() -> Box) -> Self { + self.responder = Some(acceptor); + self + } - pub async fn start(self) -> RSocketResult { - match self.uri { - Some(v) => match v { - URI::Tcp(vv) => { - let addr = vv.parse().unwrap(); - let socket = transport::tcp::connect(&addr); - let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); - let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); - tokio::spawn(async move { crate::transport::tcp::process(socket, snd_rx, rcv_tx).await }); - let duplex_socket = DuplexSocket::new(1, snd_tx.clone()); - let duplex_socket_clone = duplex_socket.clone(); - let responder = self.responder; - tokio::spawn(async move { - let acceptor = if let Some(r) = responder { - Acceptor::Direct(r()) - } else { - Acceptor::Empty() - }; - duplex_socket_clone.event_loop(acceptor, rcv_rx).await; - }); - let setup = self.setup.build(); - duplex_socket.setup(setup).await; - Ok(Client::new(duplex_socket)) + pub async fn start(self) -> RSocketResult { + match self.uri { + Some(v) => match v { + URI::Tcp(vv) => { + let addr = vv.parse().unwrap(); + let socket = transport::tcp::connect(&addr); + let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); + let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); + tokio::spawn(async move { + crate::transport::tcp::process(socket, snd_rx, rcv_tx).await + }); + let duplex_socket = DuplexSocket::new(1, snd_tx.clone()); + let duplex_socket_clone = duplex_socket.clone(); + let responder = self.responder; + tokio::spawn(async move { + let acceptor = if let Some(r) = responder { + Acceptor::Direct(r()) + } else { + Acceptor::Empty() + }; + duplex_socket_clone.event_loop(acceptor, rcv_rx).await; + }); + let setup = self.setup.build(); + duplex_socket.setup(setup).await; + Ok(Client::new(duplex_socket)) + } + _ => Err(RSocketError::from("unsupported uri")), + }, + None => Err(RSocketError::from("missing rsocket uri")), } - _ => Err(RSocketError::from("unsupported uri")), - }, - None => Err(RSocketError::from("missing rsocket uri")), } - } } impl RSocket for Client { - fn metadata_push(&self, req: Payload) -> Mono<()> { - self.socket.metadata_push(req) - } - fn fire_and_forget(&self, req: Payload) -> Mono<()> { - self.socket.fire_and_forget(req) - } - fn request_response(&self, req: Payload) -> Mono { - self.socket.request_response(req) - } - fn request_stream(&self, req: Payload) -> Flux { - self.socket.request_stream(req) - } - fn request_channel(&self, reqs: Flux) -> Flux { - self.socket.request_channel(reqs) - } + fn metadata_push(&self, req: Payload) -> Mono<()> { + self.socket.metadata_push(req) + } + fn fire_and_forget(&self, req: Payload) -> Mono<()> { + self.socket.fire_and_forget(req) + } + fn request_response(&self, req: Payload) -> Mono { + self.socket.request_response(req) + } + fn request_stream(&self, req: Payload) -> Flux { + self.socket.request_stream(req) + } + fn request_channel(&self, reqs: Flux) -> Flux { + self.socket.request_channel(reqs) + } } diff --git a/src/x/factory.rs b/src/x/factory.rs index 0ab49ec..d3a63fe 100644 --- a/src/x/factory.rs +++ b/src/x/factory.rs @@ -3,10 +3,10 @@ use super::{Client, ClientBuilder, ServerBuilder}; pub struct RSocketFactory; impl RSocketFactory { - pub fn connect() -> ClientBuilder { - Client::builder() - } - pub fn receive() -> ServerBuilder { - ServerBuilder::new() - } + pub fn connect() -> ClientBuilder { + Client::builder() + } + pub fn receive() -> ServerBuilder { + ServerBuilder::new() + } } diff --git a/src/x/mod.rs b/src/x/mod.rs index 7f27c7f..01bb1ab 100644 --- a/src/x/mod.rs +++ b/src/x/mod.rs @@ -3,7 +3,7 @@ mod factory; mod server; mod uri; -pub use server::{ServerBuilder}; pub use client::{Client, ClientBuilder}; pub use factory::RSocketFactory; +pub use server::ServerBuilder; pub use uri::URI; diff --git a/src/x/server.rs b/src/x/server.rs index dd03c36..a1f374b 100644 --- a/src/x/server.rs +++ b/src/x/server.rs @@ -10,65 +10,67 @@ use tokio::net::TcpListener; use tokio::sync::mpsc; fn on_setup_noop(_setup: SetupPayload, _socket: Box) -> Box { - Box::new(EmptyRSocket) + Box::new(EmptyRSocket) } pub struct ServerBuilder { - uri: Option, - on_setup: fn(SetupPayload, Box) -> Box, + uri: Option, + on_setup: fn(SetupPayload, Box) -> Box, } impl Default for ServerBuilder { - fn default() -> Self { - Self::new() - } + fn default() -> Self { + Self::new() + } } impl ServerBuilder { - pub fn new() -> ServerBuilder { - ServerBuilder { - uri: None, - on_setup: on_setup_noop, + pub fn new() -> ServerBuilder { + ServerBuilder { + uri: None, + on_setup: on_setup_noop, + } } - } - pub fn acceptor( - mut self, - handler: fn(SetupPayload, Box) -> Box, - ) -> Self { - self.on_setup = handler; - self - } + pub fn acceptor( + mut self, + handler: fn(SetupPayload, Box) -> Box, + ) -> Self { + self.on_setup = handler; + self + } - pub fn transport(mut self, uri: URI) -> Self { - self.uri = Some(uri); - self - } + pub fn transport(mut self, uri: URI) -> Self { + self.uri = Some(uri); + self + } - pub async fn serve(self) -> Result<(), Box> { - let uri = self.uri.clone().unwrap(); - match uri { - URI::Tcp(v) => { - let addr: SocketAddr = v.parse().unwrap(); - let mut listener = TcpListener::bind(&addr).await.unwrap(); - debug!("Listening on: {}", addr); - loop { - let (socket, _) = listener.accept().await.unwrap(); - let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); - let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); + pub async fn serve(self) -> Result<(), Box> { + let uri = self.uri.clone().unwrap(); + match uri { + URI::Tcp(v) => { + let addr: SocketAddr = v.parse().unwrap(); + let mut listener = TcpListener::bind(&addr).await.unwrap(); + debug!("Listening on: {}", addr); + loop { + let (socket, _) = listener.accept().await.unwrap(); + let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); + let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); - tokio::spawn(async move { crate::transport::tcp::process(socket, snd_rx, rcv_tx).await }); + tokio::spawn(async move { + crate::transport::tcp::process(socket, snd_rx, rcv_tx).await + }); - let setuper = Arc::new(self.on_setup); - let next_acceptor = move || Acceptor::Generate(setuper.clone()); - let ds = DuplexSocket::new(0, snd_tx.clone()); - tokio::spawn(async move { - let acceptor = next_acceptor(); - ds.event_loop(acceptor, rcv_rx).await; - }); + let setuper = Arc::new(self.on_setup); + let next_acceptor = move || Acceptor::Generate(setuper.clone()); + let ds = DuplexSocket::new(0, snd_tx.clone()); + tokio::spawn(async move { + let acceptor = next_acceptor(); + ds.event_loop(acceptor, rcv_rx).await; + }); + } + } + _ => unimplemented!(), } - } - _ => unimplemented!(), } - } } diff --git a/src/x/uri.rs b/src/x/uri.rs index ea61de8..e25304a 100644 --- a/src/x/uri.rs +++ b/src/x/uri.rs @@ -1,5 +1,5 @@ #[derive(Debug, Clone)] pub enum URI { - Tcp(String), - Websocket(String), + Tcp(String), + Websocket(String), } diff --git a/tests/frames.rs b/tests/frames.rs index 43b2b44..6efada6 100644 --- a/tests/frames.rs +++ b/tests/frames.rs @@ -7,127 +7,127 @@ use rsocket_rust::frame::*; #[test] fn test_setup() { - let f = Setup::builder(1234, 0) - .set_mime_data("application/binary") - .set_mime_metadata("text/plain") - .set_token(Bytes::from("this_is_a_token")) - .set_data(Bytes::from(String::from("Hello World!"))) - .set_metadata(Bytes::from(String::from("foobar"))) - .build(); - try_codec(f); + let f = Setup::builder(1234, 0) + .set_mime_data("application/binary") + .set_mime_metadata("text/plain") + .set_token(Bytes::from("this_is_a_token")) + .set_data(Bytes::from(String::from("Hello World!"))) + .set_metadata(Bytes::from(String::from("foobar"))) + .build(); + try_codec(f); } #[test] fn test_keepalive() { - let f = Keepalive::builder(1234, FLAG_RESPOND) - .set_last_received_position(123) - .set_data(Bytes::from("foobar")) - .build(); - try_codec(f); + let f = Keepalive::builder(1234, FLAG_RESPOND) + .set_last_received_position(123) + .set_data(Bytes::from("foobar")) + .build(); + try_codec(f); } #[test] fn test_request_response() { - let f = RequestResponse::builder(1234, 0) - .set_data(Bytes::from("Hello World")) - .set_metadata(Bytes::from("Foobar")) - .build(); - try_codec(f); + let f = RequestResponse::builder(1234, 0) + .set_data(Bytes::from("Hello World")) + .set_metadata(Bytes::from("Foobar")) + .build(); + try_codec(f); } #[test] fn test_payload() { - let f = Payload::builder(1234, FLAG_NEXT | FLAG_COMPLETE) - .set_data(Bytes::from("Hello World!")) - .set_metadata(Bytes::from("foobar")) - .build(); - try_codec(f); + let f = Payload::builder(1234, FLAG_NEXT | FLAG_COMPLETE) + .set_data(Bytes::from("Hello World!")) + .set_metadata(Bytes::from("foobar")) + .build(); + try_codec(f); } #[test] fn test_request_channel() { - let f = RequestChannel::builder(1234, 0) - .set_initial_request_n(1) - .set_data(Bytes::from("Hello World!")) - .set_metadata(Bytes::from("foobar")) - .build(); - try_codec(f); + let f = RequestChannel::builder(1234, 0) + .set_initial_request_n(1) + .set_data(Bytes::from("Hello World!")) + .set_metadata(Bytes::from("foobar")) + .build(); + try_codec(f); } #[test] fn test_cancel() { - let f = Cancel::builder(1234, 0).build(); - try_codec(f); + let f = Cancel::builder(1234, 0).build(); + try_codec(f); } #[test] fn test_request_fnf() { - let f = RequestFNF::builder(1234, 0) - .set_data(Bytes::from("Hello")) - .set_metadata(Bytes::from("World")) - .build(); - try_codec(f); + let f = RequestFNF::builder(1234, 0) + .set_data(Bytes::from("Hello")) + .set_metadata(Bytes::from("World")) + .build(); + try_codec(f); } #[test] fn test_metadata_push() { - let f = MetadataPush::builder(1234, 0) - .set_metadata(Bytes::from("Hello Rust!")) - .build(); - try_codec(f); + let f = MetadataPush::builder(1234, 0) + .set_metadata(Bytes::from("Hello Rust!")) + .build(); + try_codec(f); } #[test] fn test_request_n() { - let f = RequestN::builder(1234, 0).set_n(77778888).build(); - try_codec(f); + let f = RequestN::builder(1234, 0).set_n(77778888).build(); + try_codec(f); } #[test] fn test_lease() { - let f = Lease::builder(1234, 0) - .set_metadata(Bytes::from("Hello Rust!")) - .set_number_of_requests(333) - .set_ttl(1000) - .build(); - try_codec(f); + let f = Lease::builder(1234, 0) + .set_metadata(Bytes::from("Hello Rust!")) + .set_number_of_requests(333) + .set_ttl(1000) + .build(); + try_codec(f); } #[test] fn test_error() { - let f = Error::builder(1234, 0) - .set_data(Bytes::from("Hello World!")) - .set_code(4444) - .build(); - try_codec(f); + let f = Error::builder(1234, 0) + .set_data(Bytes::from("Hello World!")) + .set_code(4444) + .build(); + try_codec(f); } #[test] fn resume_ok() { - let f = ResumeOK::builder(1234, 0).set_position(2333).build(); - try_codec(f); + let f = ResumeOK::builder(1234, 0).set_position(2333).build(); + try_codec(f); } #[test] fn test_resume() { - let f = Resume::builder(0, FLAG_RESUME) - .set_last_received_server_position(123) - .set_first_available_client_position(22) - .set_token(Bytes::from("this is a token")) - .build(); - try_codec(f); + let f = Resume::builder(0, FLAG_RESUME) + .set_last_received_server_position(123) + .set_first_available_client_position(22) + .set_token(Bytes::from("this is a token")) + .build(); + try_codec(f); } fn try_codec(f: Frame) { - println!("******* codec: {:?}", f); - let mut bf = BytesMut::with_capacity(f.len() as usize); - f.write_to(&mut bf); - println!("####### encode: {}", hex::encode(bf.to_vec())); - let f2 = Frame::decode(&mut bf).unwrap(); - println!("####### decode: {:?}", f2); - assert_eq!( - f, f2, - "frames doesn't match: expect={:?}, actual={:?}", - f, f2 - ); + println!("******* codec: {:?}", f); + let mut bf = BytesMut::with_capacity(f.len() as usize); + f.write_to(&mut bf); + println!("####### encode: {}", hex::encode(bf.to_vec())); + let f2 = Frame::decode(&mut bf).unwrap(); + println!("####### decode: {:?}", f2); + assert_eq!( + f, f2, + "frames doesn't match: expect={:?}, actual={:?}", + f, f2 + ); } From bd2109e6e4bb58497b5b6f3a28bc37af6dcbc15f Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Wed, 4 Dec 2019 21:39:41 +0800 Subject: [PATCH 02/10] optimize rsocket uri parser. foobar foobar foobar --- Cargo.toml | 9 +- README.md | 17 ++- examples/echo/main.rs | 10 +- examples/proxy/main.rs | 32 ++++++ src/errors.rs | 52 ++++++--- src/extension.rs | 1 - src/frame/error.rs | 8 ++ src/frame/mod.rs | 14 +-- src/lib.rs | 11 +- src/prelude.rs | 6 -- src/spi.rs | 53 ++++----- src/transport/mod.rs | 2 +- src/transport/socket.rs | 180 ++++++++++++++++++------------- src/transport/spi.rs | 11 ++ src/x/client.rs | 82 +++++++------- src/x/mod.rs | 1 - src/x/server.rs | 96 ++++++++++------- src/x/uri.rs | 41 ++++++- tests/clients.rs | 42 ++++++-- tests/composite_metadata_test.rs | 2 - 20 files changed, 426 insertions(+), 244 deletions(-) create mode 100644 examples/proxy/main.rs delete mode 100644 src/prelude.rs diff --git a/Cargo.toml b/Cargo.toml index f08d88c..a309e96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rsocket_rust" -version = "0.3.0" +version = "0.4.0" authors = ["Jeffsky "] edition = "2018" license = "Apache-2.0" @@ -15,6 +15,7 @@ log = "0.4.8" bytes = "0.5.2" futures = "0.3.1" lazy_static = "1.4.0" +url = "2.1.0" # reactor_rs = {git = "https://github.com/jjeffcaii/reactor-rust", branch = "develop"} [dependencies.tokio] @@ -36,6 +37,6 @@ rand = "0.7.2" name = "echo" path = "examples/echo/main.rs" -# [[example]] -# name = "proxy" -# path = "examples/proxy/main.rs" +[[example]] +name = "proxy" +path = "examples/proxy/main.rs" diff --git a/README.md b/README.md index 880d30e..4965962 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ [![GitHub Release](https://img.shields.io/github/release-pre/rsocket/rsocket-rust.svg)](https://github.com/rsocket/rsocket-rust/releases) > rsocket-rust is an implementation of the RSocket protocol in Rust(1.39+). -It's an **alpha** version and still under active development. **Do not use it in a production environment!** +It's an **alpha** version and still under active development. +**Do not use it in a production environment!** ## Example @@ -26,10 +27,10 @@ use std::error::Error; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::builder().init(); - let addr = env::args().nth(1).unwrap_or("127.0.0.1:7878".to_string()); + let addr = env::args().nth(1).unwrap_or("tcp://127.0.0.1:7878".to_string()); RSocketFactory::receive() - .transport(URI::Tcp(addr)) + .transport(&addr) .acceptor(|setup, _socket| { info!("accept setup: {:?}", setup); Box::new(EchoRSocket) @@ -51,7 +52,7 @@ use rsocket_rust::prelude::*; async fn test() { let cli = RSocketFactory::connect() .acceptor(|| Box::new(EchoRSocket)) - .transport(URI::Tcp("127.0.0.1:7878".to_string())) + .transport("tcp://127.0.0.1:7878") .setup(Payload::from("READY!")) .mime_type("text/plain", "text/plain") .start() @@ -81,6 +82,14 @@ async fn test() { - [x] REQUEST_RESPONSE - [x] REQUEST_STREAM - [x] REQUEST_CHANNEL +- More Operations + - [ ] Error + - [ ] Cancel + - [ ] Fragmentation + - [ ] Resume +- QoS + - [ ] RequestN + - [ ] Lease - Transport - [x] TCP - [ ] Websocket diff --git a/examples/echo/main.rs b/examples/echo/main.rs index 0ea0d23..806d9d3 100644 --- a/examples/echo/main.rs +++ b/examples/echo/main.rs @@ -8,15 +8,17 @@ use std::error::Error; #[tokio::main] async fn main() -> Result<(), Box> { - env_logger::builder().init(); - let addr = env::args().nth(1).unwrap_or("127.0.0.1:7878".to_string()); - + env_logger::builder().format_timestamp_millis().init(); + let addr = env::args() + .nth(1) + .unwrap_or("tcp://127.0.0.1:7878".to_string()); RSocketFactory::receive() - .transport(URI::Tcp(addr)) + .transport(&addr) .acceptor(|setup, _socket| { info!("accept setup: {:?}", setup); Box::new(EchoRSocket) }) + .on_start(|| info!("+++++++ echo server started! +++++++")) .serve() .await } diff --git a/examples/proxy/main.rs b/examples/proxy/main.rs new file mode 100644 index 0000000..7fbe186 --- /dev/null +++ b/examples/proxy/main.rs @@ -0,0 +1,32 @@ +#[macro_use] +extern crate log; +extern crate env_logger; +extern crate futures; +extern crate rsocket_rust; +extern crate tokio; + +use futures::executor::block_on; +use rsocket_rust::prelude::*; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + env_logger::builder().format_timestamp_millis().init(); + + RSocketFactory::receive() + .acceptor(|setup, _sending_socket| { + info!("incoming socket: setup={:?}", setup); + Box::new(block_on(async move { + RSocketFactory::connect() + .acceptor(|| Box::new(EchoRSocket)) + .setup(Payload::from("I'm Rust!")) + .transport("tcp://127.0.0.1:7878") + .start() + .await + .unwrap() + })) + }) + .transport("tcp://127.0.0.1:7979") + .serve() + .await +} diff --git a/src/errors.rs b/src/errors.rs index 70f24fd..4cca34a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -2,13 +2,23 @@ use std::error::Error; use std::fmt; use std::io; +pub const ERR_INVALID_SETUP: u32 = 0x0000_0001; +pub const ERR_UNSUPPORTED_SETUP: u32 = 0x0000_0002; +pub const ERR_REJECT_SETUP: u32 = 0x0000_0003; +pub const ERR_REJECT_RESUME: u32 = 0x0000_0004; +pub const ERR_CONN_FAILED: u32 = 0x0000_0101; +pub const ERR_CONN_CLOSED: u32 = 0x0000_0102; +pub const ERR_APPLICATION: u32 = 0x0000_0201; +pub const ERR_REJECTED: u32 = 0x0000_0202; +pub const ERR_CANCELED: u32 = 0x0000_0203; +pub const ERR_INVALID: u32 = 0x0000_0204; + #[derive(Debug)] pub enum ErrorKind { - Internal(u32, &'static str), + Internal(u32, String), WithDescription(String), IO(io::Error), Cancelled(), - Send(), } #[derive(Debug)] @@ -16,26 +26,19 @@ pub struct RSocketError { kind: ErrorKind, } -impl Error for RSocketError { - fn description(&self) -> &str { - "this is a rsocket error" - } +impl Error for RSocketError {} - fn cause(&self) -> Option<&dyn Error> { +impl fmt::Display for RSocketError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match &self.kind { - ErrorKind::IO(e) => Some(e), - _ => None, + ErrorKind::Internal(c, s) => write!(f, "ERROR({}): {}", translate(c), s), + ErrorKind::WithDescription(s) => write!(f, "{}", s), + ErrorKind::IO(e) => write!(f, "{}", e), + ErrorKind::Cancelled() => write!(f, "ERROR(CANCELLED)"), } } } -impl fmt::Display for RSocketError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - println!(">>>>>>>>>>> {:?}", self.kind); - unimplemented!() - } -} - impl From for RSocketError { fn from(kind: ErrorKind) -> RSocketError { RSocketError { kind } @@ -56,3 +59,20 @@ impl From<&'static str> for RSocketError { } } } + +#[inline] +fn translate(code: &u32) -> &str { + match *code { + ERR_APPLICATION => "APPLICATION", + ERR_INVALID_SETUP => "INVALID_SETUP", + ERR_UNSUPPORTED_SETUP => "UNSUPPORTED_SETUP", + ERR_REJECT_SETUP => "REJECT_SETUP", + ERR_REJECT_RESUME => "REJECT_RESUME", + ERR_CONN_FAILED => "CONN_FAILED", + ERR_CONN_CLOSED => "CONN_CLOSED", + ERR_REJECTED => "REJECTED", + ERR_CANCELED => "CANCELED", + ERR_INVALID => "INVALID", + _ => "UNKNOWN", + } +} diff --git a/src/extension.rs b/src/extension.rs index db01f85..11ad371 100644 --- a/src/extension.rs +++ b/src/extension.rs @@ -26,7 +26,6 @@ impl RoutingMetadataBuilder { pub fn push_str(self, tag: &str) -> Self { self.push(String::from(tag)) } - pub fn push(mut self, tag: String) -> Self { if tag.len() > MAX_ROUTING_TAG_LEN { panic!("exceeded maximum routing tag length!"); diff --git a/src/frame/error.rs b/src/frame/error.rs index 4cafe34..6c00c06 100644 --- a/src/frame/error.rs +++ b/src/frame/error.rs @@ -1,6 +1,7 @@ use super::{Body, Frame, Writeable}; use crate::result::RSocketResult; use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::fmt; #[derive(Debug, PartialEq)] pub struct Error { @@ -56,6 +57,13 @@ impl Error { ErrorBuilder::new(stream_id, flag) } + pub fn get_data_utf8(&self) -> String { + match self.get_data() { + Some(b) => String::from_utf8(b.to_vec()).unwrap(), + None => String::from(""), + } + } + pub fn get_data(&self) -> &Option { &self.data } diff --git a/src/frame/mod.rs b/src/frame/mod.rs index 4ae6cd1..7b77151 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -60,17 +60,6 @@ pub const TYPE_METADATA_PUSH: u16 = 0x0C; pub const TYPE_RESUME: u16 = 0x0D; pub const TYPE_RESUME_OK: u16 = 0x0E; -pub const ERR_INVALID_SETUP: u32 = 0x0000_0001; -pub const ERR_UNSUPPORTED_SETUP: u32 = 0x0000_0002; -pub const ERR_REJECT_SETUP: u32 = 0x0000_0003; -pub const ERR_REJECT_RESUME: u32 = 0x0000_0004; -pub const ERR_CONN_FAILED: u32 = 0x0000_0101; -pub const ERR_CONN_CLOSED: u32 = 0x0000_0102; -pub const ERR_APPLICATION: u32 = 0x0000_0201; -pub const ERR_REJECTED: u32 = 0x0000_0202; -pub const ERR_CANCELED: u32 = 0x0000_0203; -pub const ERR_INVALID: u32 = 0x0000_0204; - pub const REQUEST_MAX: u32 = 0x7FFF_FFFF; // 2147483647 const LEN_HEADER: usize = 6; @@ -181,7 +170,7 @@ impl Frame { TYPE_ERROR => Error::decode(flag, b).map(Body::Error), TYPE_RESUME_OK => ResumeOK::decode(flag, b).map(Body::ResumeOK), TYPE_RESUME => Resume::decode(flag, b).map(Body::Resume), - _ => Err(RSocketError::from("illegal frame type")), + _ => Err(RSocketError::from(format!("illegal frame type: {}", kind))), }; body.map(|it| Frame::new(sid, it, flag)) } @@ -211,6 +200,7 @@ impl Frame { } } +#[inline] fn to_frame_type(body: &Body) -> u16 { match body { Body::Setup(_) => TYPE_SETUP, diff --git a/src/lib.rs b/src/lib.rs index adec218..ebc950c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,13 +12,20 @@ extern crate matches; pub mod extension; pub mod frame; pub mod mime; -pub mod transport; // mod core; mod errors; mod payload; mod result; mod spi; +mod transport; mod x; -pub mod prelude; +pub mod prelude { + pub use crate::errors::*; + pub use crate::payload::*; + pub use crate::result::*; + pub use crate::spi::*; + pub use crate::x::{Client, RSocketFactory}; + pub use futures::{Sink, SinkExt, Stream, StreamExt}; +} diff --git a/src/prelude.rs b/src/prelude.rs deleted file mode 100644 index 23eea20..0000000 --- a/src/prelude.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub use crate::errors::*; -pub use crate::payload::*; -pub use crate::result::*; -pub use crate::spi::*; -pub use crate::x::{Client, RSocketFactory, URI}; -pub use futures::{Sink, SinkExt, Stream, StreamExt}; diff --git a/src/spi.rs b/src/spi.rs index 3fe85cb..98f1a11 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -1,22 +1,24 @@ -use crate::errors::{ErrorKind, RSocketError}; +use crate::errors::{self, ErrorKind, RSocketError}; use crate::frame; use crate::payload::{Payload, SetupPayload}; use crate::result::RSocketResult; + use futures::future; use futures::{Sink, SinkExt, Stream, StreamExt}; use std::future::Future; use std::pin::Pin; +use std::result::Result; use std::sync::Arc; use tokio::sync::mpsc; // TODO: switch to reactor-rust. -pub type Mono = Pin>>>; -pub type Flux = Pin>>>; +pub type Mono = Pin>>; +pub type Flux = Pin>>; pub trait RSocket: Sync + Send { fn metadata_push(&self, req: Payload) -> Mono<()>; fn fire_and_forget(&self, req: Payload) -> Mono<()>; - fn request_response(&self, req: Payload) -> Mono; + fn request_response(&self, req: Payload) -> Mono>; fn request_stream(&self, req: Payload) -> Flux; fn request_channel(&self, reqs: Flux) -> Flux; } @@ -26,31 +28,27 @@ pub struct EchoRSocket; impl RSocket for EchoRSocket { fn metadata_push(&self, req: Payload) -> Mono<()> { info!("{:?}", req); - Box::pin(future::ok::<(), RSocketError>(())) + Box::pin(async {}) } fn fire_and_forget(&self, req: Payload) -> Mono<()> { info!("{:?}", req); - Box::pin(future::ok::<(), RSocketError>(())) + Box::pin(async {}) } - fn request_response(&self, req: Payload) -> Mono { + fn request_response(&self, req: Payload) -> Mono> { info!("{:?}", req); - Box::pin(future::ok::(req)) + Box::pin(async move { Ok(req) }) } fn request_stream(&self, req: Payload) -> Flux { info!("{:?}", req); - Box::pin(futures::stream::iter(vec![ - Ok(req.clone()), - Ok(req.clone()), - Ok(req), - ])) + // repeat 3 times. + Box::pin(futures::stream::iter(vec![req.clone(), req.clone(), req])) } fn request_channel(&self, mut reqs: Flux) -> Flux { - let (sender, receiver) = mpsc::unbounded_channel::>(); + let (sender, receiver) = mpsc::unbounded_channel::(); tokio::spawn(async move { while let Some(it) = reqs.next().await { - let pa = it.unwrap(); - info!("{:?}", pa); - sender.send(Ok(pa)).unwrap(); + info!("{:?}", it); + sender.send(it).unwrap(); } }); Box::pin(receiver) @@ -63,35 +61,28 @@ pub struct EmptyRSocket; impl EmptyRSocket { fn must_failed(&self) -> RSocketError { - RSocketError::from(ErrorKind::Internal(frame::ERR_APPLICATION, "NOT_IMPLEMENT")) + let kind = ErrorKind::Internal(errors::ERR_APPLICATION, String::from("NOT_IMPLEMENT")); + RSocketError::from(kind) } } impl RSocket for EmptyRSocket { fn metadata_push(&self, _req: Payload) -> Mono<()> { - Box::pin(future::err(self.must_failed())) + Box::pin(async {}) } fn fire_and_forget(&self, _req: Payload) -> Mono<()> { - Box::pin(future::err(self.must_failed())) + Box::pin(async {}) } - fn request_response(&self, _req: Payload) -> Mono { + fn request_response(&self, _req: Payload) -> Mono> { Box::pin(future::err(self.must_failed())) } fn request_stream(&self, _req: Payload) -> Flux { - Box::pin(futures::stream::iter(vec![Err(self.must_failed())])) + Box::pin(futures::stream::empty()) } fn request_channel(&self, _reqs: Flux) -> Flux { - Box::pin(futures::stream::iter(vec![Err(self.must_failed())])) + Box::pin(futures::stream::empty()) } } - -pub type AcceptorGenerator = Arc) -> Box>; - -pub enum Acceptor { - Direct(Box), - Generate(AcceptorGenerator), - Empty(), -} diff --git a/src/transport/mod.rs b/src/transport/mod.rs index f9a3a81..4c5bdda 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -5,4 +5,4 @@ mod spi; pub(crate) mod tcp; pub(crate) use codec::RFrameCodec; pub(crate) use socket::DuplexSocket; -pub use spi::{Rx, Transport, Tx}; +pub(crate) use spi::{Acceptor, Rx, Transport, Tx}; diff --git a/src/transport/socket.rs b/src/transport/socket.rs index ad660a7..04dfed3 100644 --- a/src/transport/socket.rs +++ b/src/transport/socket.rs @@ -1,10 +1,10 @@ use super::misc::{self, Counter, StreamID}; -use super::spi::{Rx, Transport, Tx}; -use crate::errors::{ErrorKind, RSocketError}; +use super::spi::{Acceptor, Rx, Transport, Tx}; +use crate::errors::{ErrorKind, RSocketError, ERR_APPLICATION}; use crate::frame::{self, Body, Frame}; use crate::payload::{Payload, SetupPayload}; use crate::result::RSocketResult; -use crate::spi::{Acceptor, EmptyRSocket, Flux, Mono, RSocket}; +use crate::spi::{EmptyRSocket, Flux, Mono, RSocket}; use bytes::{Buf, BufMut, Bytes, BytesMut}; use futures::{future, Sink, SinkExt, Stream, StreamExt}; use std::collections::HashMap; @@ -13,12 +13,17 @@ use std::error::Error; use std::future::Future; use std::pin::Pin; use std::ptr; +use std::result::Result; use std::sync::{Arc, Mutex, RwLock}; use tokio::net::TcpListener; use tokio::prelude::*; use tokio::sync::oneshot::{Receiver, Sender}; use tokio::sync::{mpsc, oneshot}; +type Single = oneshot::Sender>; +type Multi = mpsc::UnboundedSender; +type MultiReceiver = mpsc::UnboundedReceiver; + #[derive(Clone)] pub(crate) struct DuplexSocket { seq: StreamID, @@ -32,10 +37,6 @@ struct Responder { inner: Arc>>, } -type Single = oneshot::Sender>; -type Multi = mpsc::UnboundedSender>; -type MultiReceiver = mpsc::UnboundedReceiver>; - #[derive(Debug)] enum Handler { Request(Single), @@ -79,12 +80,7 @@ impl DuplexSocket { if let Some(b) = m { bu = bu.set_metadata(b); } - self.send_frame(bu.build()).await; - } - - async fn send_frame(&self, sending: Frame) { - let tx = self.tx.clone(); - tx.send(sending).unwrap(); + self.tx.send(bu.build()).unwrap(); } fn register_handler(&self, sid: u32, handler: Handler) { @@ -123,7 +119,6 @@ impl DuplexSocket { self.on_request_stream(sid, flag, input).await; } Body::RequestChannel(v) => { - // TODO: support channel let input = Payload::from(v); self.on_request_channel(sid, flag, input).await; } @@ -142,9 +137,10 @@ impl DuplexSocket { } Body::Error(v) => { // TODO: support error + self.on_error(sid, flag, v).await; } Body::Cancel() => { - // TODO: support cancel + self.on_cancel(sid, flag).await; } Body::Lease(v) => { // TODO: support Lease @@ -153,6 +149,48 @@ impl DuplexSocket { } } + #[inline] + async fn on_error(&self, sid: u32, flag: u16, input: frame::Error) { + // pick handler + let handlers = self.handlers.clone(); + let mut senders = handlers.map.write().unwrap(); + + if let Some(handler) = senders.remove(&sid) { + let kind = ErrorKind::Internal(input.get_code(), input.get_data_utf8()); + let e = Err(RSocketError::from(kind)); + match handler { + Handler::Request(sender) => { + sender.send(e).unwrap(); + } + _ => unimplemented!(), + } + } + } + + #[inline] + async fn on_cancel(&self, sid: u32, flag: u16) { + // TODO: support cancel + // pick handler + let handlers = self.handlers.clone(); + let mut senders = handlers.map.write().unwrap(); + + if let Some(handler) = senders.remove(&sid) { + let e = Err(RSocketError::from(ErrorKind::Cancelled())); + match handler { + Handler::Request(sender) => { + info!("REQUEST_RESPONSE {} cancelled!", sid); + sender.send(e).unwrap(); + } + Handler::Stream(sender) => { + info!("REQUEST_STREAM {} cancelled!", sid); + } + Handler::Channel((sender, c)) => { + info!("REQUEST_CHANNEL {} cancelled!", sid); + } + }; + } + } + #[inline] async fn on_payload(&self, sid: u32, flag: u16, input: Payload) { // pick handler @@ -163,7 +201,7 @@ impl DuplexSocket { Handler::Request(sender) => sender.send(Ok(input)).unwrap(), Handler::Stream(sender) => { if flag & frame::FLAG_NEXT != 0 { - sender.send(Ok(input)).unwrap(); + sender.send(input).unwrap(); } if flag & frame::FLAG_COMPLETE == 0 { senders.insert(sid, Handler::Stream(sender)); @@ -172,7 +210,7 @@ impl DuplexSocket { Handler::Channel((sender, cdl)) => { // TODO: support channel if flag & frame::FLAG_NEXT != 0 { - sender.send(Ok(input)).unwrap(); + sender.send(input).unwrap(); } if flag & frame::FLAG_COMPLETE == 0 { senders.insert(sid, Handler::Channel((sender, cdl))); @@ -184,24 +222,21 @@ impl DuplexSocket { #[inline] fn on_setup(&self, acceptor: &Acceptor, sid: u32, flag: u16, setup: SetupPayload) { match acceptor { + Acceptor::Simple(gen) => { + self.responder.set(gen()); + } Acceptor::Generate(gen) => { self.responder.set(gen(setup, Box::new(self.clone()))); } Acceptor::Empty() => { self.responder.set(Box::new(EmptyRSocket)); } - // TODO: How to direct??? - // Acceptor::Direct(sk) => self.responder.set(sk), - _ => (), } } #[inline] async fn on_fire_and_forget(&self, sid: u32, flag: u16, input: Payload) { - match self.responder.clone().fire_and_forget(input).await { - Ok(()) => (), - Err(e) => error!("respoond fnf failed: {}", e), - } + self.responder.clone().fire_and_forget(input).await } #[inline] @@ -222,11 +257,13 @@ impl DuplexSocket { bu.build() } Err(e) => frame::Error::builder(sid, 0) - .set_code(frame::ERR_APPLICATION) + .set_code(ERR_APPLICATION) .set_data(Bytes::from("TODO: should be error details")) .build(), }; - tx.send(sending).unwrap(); + if let Err(e) = tx.send(sending) { + error!("respond REQUEST_RESPONSE failed: {}", e); + } }); } @@ -237,8 +274,7 @@ impl DuplexSocket { tokio::spawn(async move { let mut payloads = responder.request_stream(input); while let Some(it) = payloads.next().await { - // TODO: process error. - let (d, m) = it.unwrap().split(); + let (d, m) = it.split(); let mut bu = frame::Payload::builder(sid, frame::FLAG_NEXT); if let Some(b) = d { bu = bu.set_data(b); @@ -258,8 +294,8 @@ impl DuplexSocket { async fn on_request_channel(&self, sid: u32, flag: u16, first: Payload) { let responder = self.responder.clone(); let tx = self.tx.clone(); - let (sender, receiver) = mpsc::unbounded_channel::>(); - sender.send(Ok(first)).unwrap(); + let (sender, receiver) = mpsc::unbounded_channel::(); + sender.send(first).unwrap(); let cdl = Counter::new(2); self.register_handler(sid, Handler::Channel((sender, cdl.clone()))); tokio::spawn(async move { @@ -268,10 +304,13 @@ impl DuplexSocket { let mut outputs = responder.request_channel(inputs); // TODO: support custom RequestN. let request_n = frame::RequestN::builder(sid, 0).build(); - tx.send(request_n).unwrap(); + + if let Err(e) = tx.send(request_n) { + error!("respond REQUEST_N failed: {}", e); + } while let Some(v) = outputs.next().await { - let (d, m) = v.unwrap().split(); + let (d, m) = v.split(); let mut bu = frame::Payload::builder(sid, frame::FLAG_NEXT); if let Some(b) = d { bu = bu.set_data(b); @@ -279,19 +318,20 @@ impl DuplexSocket { if let Some(b) = m { bu = bu.set_metadata(b); } - let sending = bu.build(); - tx.send(sending).unwrap(); + if let Err(e) = tx.send(bu.build()) { + error!("respond REQUEST_CHANNEL failed: {}", e); + } } let complete = frame::Payload::builder(sid, frame::FLAG_COMPLETE).build(); - tx.send(complete).unwrap(); + if let Err(e) = tx.send(complete) { + error!("complete REQUEST_CHANNEL failed: {}", e); + } }); } #[inline] async fn on_metadata_push(&self, input: Payload) { - if let Err(e) = self.responder.clone().metadata_push(input).await { - error!("metadata_push failed: {}", e); - } + self.responder.clone().metadata_push(input).await } #[inline] @@ -302,17 +342,9 @@ impl DuplexSocket { if let Some(b) = data { sending = sending.set_data(b); } - tx.send(sending.build()).unwrap(); - } - - fn request_channel22(&self, mut reqs: Flux) -> Flux { - let sid = self.seq.next(); - let tx = self.tx.clone(); - // register handler - let (sender, receiver) = mpsc::unbounded_channel::>(); - self.register_handler(sid, Handler::Stream(sender)); - tokio::spawn(async move { while let Some(req) = reqs.next().await {} }); - Box::pin(receiver) + if let Err(e) = tx.send(sending.build()) { + error!("respond KEEPALIVE failed: {}", e); + } } } @@ -326,17 +358,14 @@ impl RSocket for DuplexSocket { if let Some(b) = m { bu = bu.set_metadata(b); } - let sending = bu.build(); - match tx.send(sending) { - Ok(()) => Ok(()), - Err(_e) => Err(RSocketError::from("send metadata_push failed")), + if let Err(e) = tx.send(bu.build()) { + error!("send metadata_push failed: {}", e); } }) } fn fire_and_forget(&self, req: Payload) -> Mono<()> { let sid = self.seq.next(); let tx = self.tx.clone(); - Box::pin(async move { let (d, m) = req.split(); let mut bu = frame::RequestFNF::builder(sid, 0); @@ -346,15 +375,13 @@ impl RSocket for DuplexSocket { if let Some(b) = m { bu = bu.set_metadata(b); } - let sending = bu.build(); - match tx.send(sending) { - Ok(()) => Ok(()), - Err(_e) => Err(RSocketError::from("send fire_and_forget failed")), + if let Err(e) = tx.send(bu.build()) { + error!("send fire_and_forget failed: {}", e); } }) } - fn request_response(&self, req: Payload) -> Mono { - let (tx, rx) = oneshot::channel::>(); + fn request_response(&self, req: Payload) -> Mono> { + let (tx, rx) = oneshot::channel::>(); let sid = self.seq.next(); // register handler self.register_handler(sid, Handler::Request(tx)); @@ -370,9 +397,10 @@ impl RSocket for DuplexSocket { if let Some(b) = m { bu = bu.set_metadata(b); } - let sending = bu.build(); // send frame - sender.send(sending).unwrap(); + if let Err(e) = sender.send(bu.build()) { + error!("send request_response failed: {}", e); + } }); Box::pin(async move { match rx.await { @@ -386,7 +414,7 @@ impl RSocket for DuplexSocket { let sid = self.seq.next(); let tx = self.tx.clone(); // register handler - let (sender, receiver) = mpsc::unbounded_channel::>(); + let (sender, receiver) = mpsc::unbounded_channel::(); self.register_handler(sid, Handler::Stream(sender)); tokio::spawn(async move { let (d, m) = input.split(); @@ -398,8 +426,9 @@ impl RSocket for DuplexSocket { if let Some(b) = m { bu = bu.set_metadata(b); } - let sending = bu.build(); - tx.send(sending).unwrap(); + if let Err(e) = tx.send(bu.build()) { + error!("send request_stream failed: {}", e); + } }); Box::pin(receiver) } @@ -408,16 +437,15 @@ impl RSocket for DuplexSocket { let sid = self.seq.next(); let tx = self.tx.clone(); // register handler - let (sender, receiver) = mpsc::unbounded_channel::>(); + let (sender, receiver) = mpsc::unbounded_channel::(); let cdl = Counter::new(2); self.register_handler(sid, Handler::Channel((sender, cdl.clone()))); tokio::spawn(async move { - let mut sent: u64 = 0; + let mut first = true; while let Some(it) = reqs.next().await { - // TODO: check Err - let (d, m) = it.unwrap().split(); - sent += 1; - let sending = if sent == 1 { + let (d, m) = it.split(); + let sending = if first { + first = false; let mut bu = frame::RequestChannel::builder(sid, frame::FLAG_NEXT); if let Some(b) = d { bu = bu.set_data(b); @@ -436,11 +464,15 @@ impl RSocket for DuplexSocket { } bu.build() }; - tx.send(sending).unwrap(); + if let Err(e) = tx.send(sending) { + error!("send REQUEST_CHANNEL failed: {}", e); + } } cdl.count_down(); let sending = frame::Payload::builder(sid, frame::FLAG_COMPLETE).build(); - tx.send(sending).unwrap(); + if let Err(e) = tx.send(sending) { + error!("complete REQUEST_CHANNEL failed: {}", e); + } }); Box::pin(receiver) } @@ -488,7 +520,7 @@ impl RSocket for Responder { (*inner).fire_and_forget(req) } - fn request_response(&self, req: Payload) -> Mono { + fn request_response(&self, req: Payload) -> Mono> { let inner = self.inner.read().unwrap(); (*inner).request_response(req) } diff --git a/src/transport/spi.rs b/src/transport/spi.rs index ac21a2e..f5f08a3 100644 --- a/src/transport/spi.rs +++ b/src/transport/spi.rs @@ -1,5 +1,8 @@ use crate::frame::Frame; +use crate::payload::SetupPayload; +use crate::spi::RSocket; use std::future::Future; +use std::sync::Arc; use tokio::sync::mpsc::{Receiver, Sender, UnboundedReceiver, UnboundedSender}; pub type Tx = UnboundedSender; @@ -19,3 +22,11 @@ impl Transport { (self.tx, self.rx) } } + +type FnAcceptorWithSetup = fn(SetupPayload, Box) -> Box; + +pub(crate) enum Acceptor { + Simple(Arc Box>), + Generate(Arc), + Empty(), +} diff --git a/src/x/client.rs b/src/x/client.rs index 04e0705..99181b8 100644 --- a/src/x/client.rs +++ b/src/x/client.rs @@ -1,11 +1,14 @@ -use super::URI; +use super::uri::URI; use crate::errors::RSocketError; use crate::frame::{self, Frame}; use crate::payload::{Payload, SetupPayload, SetupPayloadBuilder}; -use crate::result::RSocketResult; -use crate::spi::{Acceptor, Flux, Mono, RSocket}; -use crate::transport::{self, DuplexSocket}; +use crate::spi::{Flux, Mono, RSocket}; +use crate::transport::{self, Acceptor, DuplexSocket}; use futures::{Future, Stream}; +use std::error::Error; +use std::net::SocketAddr; +use std::result::Result; +use std::sync::Arc; use std::time::Duration; use tokio::sync::mpsc; @@ -15,7 +18,7 @@ pub struct Client { } pub struct ClientBuilder { - uri: Option, + uri: Option, setup: SetupPayloadBuilder, responder: Option Box>, } @@ -43,8 +46,8 @@ impl ClientBuilder { } } - pub fn transport(mut self, uri: URI) -> Self { - self.uri = Some(uri); + pub fn transport(mut self, uri: &str) -> Self { + self.uri = Some(uri.to_string()); self } @@ -91,38 +94,43 @@ impl ClientBuilder { self.responder = Some(acceptor); self } - - pub async fn start(self) -> RSocketResult { - match self.uri { - Some(v) => match v { - URI::Tcp(vv) => { - let addr = vv.parse().unwrap(); - let socket = transport::tcp::connect(&addr); - let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); - let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); - tokio::spawn(async move { - crate::transport::tcp::process(socket, snd_rx, rcv_tx).await - }); - let duplex_socket = DuplexSocket::new(1, snd_tx.clone()); - let duplex_socket_clone = duplex_socket.clone(); - let responder = self.responder; - tokio::spawn(async move { - let acceptor = if let Some(r) = responder { - Acceptor::Direct(r()) - } else { - Acceptor::Empty() - }; - duplex_socket_clone.event_loop(acceptor, rcv_rx).await; - }); - let setup = self.setup.build(); - duplex_socket.setup(setup).await; - Ok(Client::new(duplex_socket)) - } - _ => Err(RSocketError::from("unsupported uri")), + pub async fn start(self) -> Result> { + // TODO: process error + let uri = self.uri.unwrap(); + match URI::parse(&uri) { + Ok(u) => match u { + URI::Tcp(vv) => Self::start_tcp(vv, self.responder, self.setup).await, + _ => unimplemented!(), }, - None => Err(RSocketError::from("missing rsocket uri")), + Err(e) => Err(e), } } + + #[inline] + async fn start_tcp( + addr: SocketAddr, + responder: Option Box>, + sb: SetupPayloadBuilder, + ) -> Result> { + let socket = transport::tcp::connect(&addr); + let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); + let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); + tokio::spawn(async move { crate::transport::tcp::process(socket, snd_rx, rcv_tx).await }); + let duplex_socket = DuplexSocket::new(1, snd_tx.clone()); + let duplex_socket_clone = duplex_socket.clone(); + + tokio::spawn(async move { + let acceptor = if let Some(r) = responder { + Acceptor::Simple(Arc::new(r)) + } else { + Acceptor::Empty() + }; + duplex_socket_clone.event_loop(acceptor, rcv_rx).await; + }); + let setup = sb.build(); + duplex_socket.setup(setup).await; + Ok(Client::new(duplex_socket)) + } } impl RSocket for Client { @@ -132,7 +140,7 @@ impl RSocket for Client { fn fire_and_forget(&self, req: Payload) -> Mono<()> { self.socket.fire_and_forget(req) } - fn request_response(&self, req: Payload) -> Mono { + fn request_response(&self, req: Payload) -> Mono> { self.socket.request_response(req) } fn request_stream(&self, req: Payload) -> Flux { diff --git a/src/x/mod.rs b/src/x/mod.rs index 01bb1ab..ba53b32 100644 --- a/src/x/mod.rs +++ b/src/x/mod.rs @@ -6,4 +6,3 @@ mod uri; pub use client::{Client, ClientBuilder}; pub use factory::RSocketFactory; pub use server::ServerBuilder; -pub use uri::URI; diff --git a/src/x/server.rs b/src/x/server.rs index a1f374b..eea4b65 100644 --- a/src/x/server.rs +++ b/src/x/server.rs @@ -1,21 +1,22 @@ -use super::URI; +use super::uri::URI; +use crate::errors::RSocketError; use crate::frame::{self, Frame}; use crate::payload::SetupPayload; -use crate::spi::{Acceptor, EmptyRSocket, RSocket}; -use crate::transport::DuplexSocket; +use crate::spi::{EmptyRSocket, RSocket}; +use crate::transport::{Acceptor, DuplexSocket}; use std::error::Error; use std::net::SocketAddr; use std::sync::Arc; use tokio::net::TcpListener; use tokio::sync::mpsc; -fn on_setup_noop(_setup: SetupPayload, _socket: Box) -> Box { - Box::new(EmptyRSocket) -} +type FnSetup = fn(SetupPayload, Box) -> Box; +type FnStart = fn(); pub struct ServerBuilder { - uri: Option, - on_setup: fn(SetupPayload, Box) -> Box, + uri: Option, + on_setup: FnSetup, + start_handler: Option, } impl Default for ServerBuilder { @@ -29,48 +30,67 @@ impl ServerBuilder { ServerBuilder { uri: None, on_setup: on_setup_noop, + start_handler: None, } } - pub fn acceptor( - mut self, - handler: fn(SetupPayload, Box) -> Box, - ) -> Self { + pub fn acceptor(mut self, handler: FnSetup) -> Self { self.on_setup = handler; self } - pub fn transport(mut self, uri: URI) -> Self { - self.uri = Some(uri); + pub fn on_start(mut self, hanlder: FnStart) -> Self { + self.start_handler = Some(hanlder); self } - pub async fn serve(self) -> Result<(), Box> { - let uri = self.uri.clone().unwrap(); - match uri { - URI::Tcp(v) => { - let addr: SocketAddr = v.parse().unwrap(); - let mut listener = TcpListener::bind(&addr).await.unwrap(); - debug!("Listening on: {}", addr); - loop { - let (socket, _) = listener.accept().await.unwrap(); - let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); - let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); + pub fn transport(mut self, addr: &str) -> Self { + self.uri = Some(String::from(addr)); + self + } - tokio::spawn(async move { - crate::transport::tcp::process(socket, snd_rx, rcv_tx).await - }); + pub async fn serve(self) -> Result<(), Box> { + // TODO: process error + let s = self.uri.unwrap(); + match URI::parse(&s) { + Ok(u) => match u { + URI::Tcp(addr) => Self::serve_tcp(addr, self.on_setup, self.start_handler).await, + _ => unimplemented!(), + }, + Err(e) => Err(e), + } + } - let setuper = Arc::new(self.on_setup); - let next_acceptor = move || Acceptor::Generate(setuper.clone()); - let ds = DuplexSocket::new(0, snd_tx.clone()); - tokio::spawn(async move { - let acceptor = next_acceptor(); - ds.event_loop(acceptor, rcv_rx).await; - }); - } - } - _ => unimplemented!(), + #[inline] + async fn serve_tcp( + addr: SocketAddr, + on_setup: FnSetup, + on_start: Option, + ) -> Result<(), Box> { + let mut listener = TcpListener::bind(&addr).await.unwrap(); + debug!("listening on: {}", addr); + if let Some(it) = on_start { + it(); + } + loop { + let (socket, _) = listener.accept().await.unwrap(); + let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); + let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); + tokio::spawn( + async move { crate::transport::tcp::process(socket, snd_rx, rcv_tx).await }, + ); + let setuper = Arc::new(on_setup); + let next_acceptor = move || Acceptor::Generate(setuper.clone()); + let ds = DuplexSocket::new(0, snd_tx.clone()); + tokio::spawn(async move { + let acceptor = next_acceptor(); + ds.event_loop(acceptor, rcv_rx).await; + }); } } } + +#[inline] +fn on_setup_noop(_setup: SetupPayload, _socket: Box) -> Box { + Box::new(EmptyRSocket) +} diff --git a/src/x/uri.rs b/src/x/uri.rs index e25304a..f1dde88 100644 --- a/src/x/uri.rs +++ b/src/x/uri.rs @@ -1,5 +1,42 @@ +use crate::errors::RSocketError; +use std::error::Error; +use std::net::SocketAddr; +use std::result::Result; +use url::Url; + +const SCHEMA_TCP: &str = "tcp"; +const SCHEMA_WS: &str = "ws"; +const DEFAULT_TCP_PORT: u16 = 7878; + #[derive(Debug, Clone)] -pub enum URI { - Tcp(String), +pub(crate) enum URI { + Tcp(SocketAddr), Websocket(String), } + +impl URI { + pub(crate) fn parse(s: &str) -> Result> { + match Url::parse(s) { + Ok(u) => Self::from_url(u), + Err(e) => Err(Box::new(e)), + } + } + + #[inline] + fn from_url(u: Url) -> Result> { + let domain = u.domain().unwrap_or("0.0.0.0"); + let schema = u.scheme(); + match schema.to_lowercase().as_ref() { + SCHEMA_TCP => { + match format!("{}:{}", domain, u.port().unwrap_or(DEFAULT_TCP_PORT)).parse() { + Ok(addr) => Ok(URI::Tcp(addr)), + Err(e) => Err(Box::new(e)), + } + } + _ => { + let e = RSocketError::from(format!("invalid schema: {}", schema)); + Err(Box::new(e)) + } + } + } +} diff --git a/tests/clients.rs b/tests/clients.rs index e280053..abf0c7f 100644 --- a/tests/clients.rs +++ b/tests/clients.rs @@ -1,22 +1,23 @@ -extern crate rsocket_rust; #[macro_use] extern crate log; -use futures::prelude::*; + use futures::stream; use rsocket_rust::prelude::*; #[tokio::main] #[test] +#[ignore] async fn test_client() { env_logger::builder().init(); let cli = RSocketFactory::connect() .acceptor(|| Box::new(EchoRSocket)) - .transport(URI::Tcp("127.0.0.1:7878".to_string())) + .transport("tcp://127.0.0.1:7878") .setup(Payload::from("READY!")) .mime_type("text/plain", "text/plain") .start() .await .unwrap(); + exec_metadata_push(&cli).await; exec_fire_and_forget(&cli).await; exec_request_response(&cli).await; @@ -25,6 +26,29 @@ async fn test_client() { cli.close(); } +#[tokio::main] +#[test] +async fn test_request_response_err() { + env_logger::builder().format_timestamp_millis().init(); + let cli = RSocketFactory::connect() + .transport("tcp://127.0.0.1:7878") + .setup(Payload::from("READY!")) + .mime_type("text/plain", "text/plain") + .start() + .await + .unwrap(); + + let res = cli + .request_response(Payload::from("must return error")) + .await; + + match res { + Ok(_) => panic!("should catch an error!"), + Err(e) => info!("error catched: {}", e), + }; + () +} + async fn exec_request_response(socket: &Client) { // request response let sending = Payload::builder() @@ -32,19 +56,19 @@ async fn exec_request_response(socket: &Client) { .set_metadata_utf8("I Rust!") .build(); let result = socket.request_response(sending).await.unwrap(); - println!("REQUEST_RESPONSE: {:?}", result); + info!("REQUEST_RESPONSE: {:?}", result); } async fn exec_metadata_push(socket: &Client) { let pa = Payload::builder().set_metadata_utf8("Hello World!").build(); // metadata push - socket.metadata_push(pa).await.unwrap(); + socket.metadata_push(pa).await; } async fn exec_fire_and_forget(socket: &Client) { // request fnf let fnf = Payload::from("Hello World!"); - socket.fire_and_forget(fnf).await.unwrap(); + socket.fire_and_forget(fnf).await; } async fn exec_request_stream(socket: &Client) { @@ -57,7 +81,7 @@ async fn exec_request_stream(socket: &Client) { let mut results = socket.request_stream(sending); loop { match results.next().await { - Some(v) => println!("STREAM_RESPONSE: {:?}", v.unwrap()), + Some(v) => info!("STREAM_RESPONSE: {:?}", v), None => break, } } @@ -70,10 +94,10 @@ async fn exec_request_channel(socket: &Client) { .set_data_utf8(&format!("Hello#{}", i)) .set_metadata_utf8("RUST") .build(); - sends.push(Ok(pa)); + sends.push(pa); } let mut results = socket.request_channel(Box::pin(stream::iter(sends))); while let Some(v) = results.next().await { - println!("====> next in channel: {:?}", v); + info!("====> next in channel: {:?}", v); } } diff --git a/tests/composite_metadata_test.rs b/tests/composite_metadata_test.rs index 95d40a2..e41cda1 100644 --- a/tests/composite_metadata_test.rs +++ b/tests/composite_metadata_test.rs @@ -1,5 +1,3 @@ -extern crate rsocket_rust; - use bytes::{Bytes, BytesMut}; use rsocket_rust::extension::*; From 05f6c71c16234fb5f23c8945e24ee0d54253974f Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Sat, 7 Dec 2019 21:01:17 +0800 Subject: [PATCH 03/10] support cancel/error for request_response. --- src/transport/misc.rs | 5 ++-- src/transport/socket.rs | 60 ++++++++++++++++++++++++++++------------- tests/clients.rs | 1 + 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/transport/misc.rs b/src/transport/misc.rs index 8f67377..7abc69e 100644 --- a/src/transport/misc.rs +++ b/src/transport/misc.rs @@ -4,6 +4,7 @@ use crate::payload::{Payload, SetupPayload}; use crate::result::RSocketResult; use crate::spi::RSocket; use futures::future; +use tokio::sync::oneshot::{self, Receiver, Sender}; use std::{ collections::HashMap, @@ -13,7 +14,6 @@ use std::{ Arc, Mutex, RwLock, }, }; -use tokio::sync::{mpsc, oneshot}; #[derive(Debug, Clone)] pub(crate) struct StreamID { @@ -51,8 +51,7 @@ impl Counter { } pub(crate) fn count_down(&self) -> i64 { - let c = self.inner.clone(); - c.fetch_add(-1, Ordering::SeqCst) + self.inner.fetch_add(-1, Ordering::SeqCst) - 1 } } diff --git a/src/transport/socket.rs b/src/transport/socket.rs index 04dfed3..f78583c 100644 --- a/src/transport/socket.rs +++ b/src/transport/socket.rs @@ -39,9 +39,10 @@ struct Responder { #[derive(Debug)] enum Handler { - Request(Single), - Stream(Multi), - Channel((Multi, Counter)), + ReqRR(Single), + ResRR(Counter), + RequestStream(Multi), + RequestChannel(Multi, Counter), } #[derive(Debug)] @@ -159,7 +160,7 @@ impl DuplexSocket { let kind = ErrorKind::Internal(input.get_code(), input.get_data_utf8()); let e = Err(RSocketError::from(kind)); match handler { - Handler::Request(sender) => { + Handler::ReqRR(sender) => { sender.send(e).unwrap(); } _ => unimplemented!(), @@ -168,23 +169,26 @@ impl DuplexSocket { } #[inline] - async fn on_cancel(&self, sid: u32, flag: u16) { + async fn on_cancel(&self, sid: u32, _flag: u16) { // TODO: support cancel // pick handler let handlers = self.handlers.clone(); let mut senders = handlers.map.write().unwrap(); - if let Some(handler) = senders.remove(&sid) { let e = Err(RSocketError::from(ErrorKind::Cancelled())); match handler { - Handler::Request(sender) => { + Handler::ReqRR(sender) => { info!("REQUEST_RESPONSE {} cancelled!", sid); sender.send(e).unwrap(); } - Handler::Stream(sender) => { + Handler::ResRR(c) => { + let lefts = c.count_down(); + info!("REQUEST_RESPONSE {} cancelled: lefts={}", sid, lefts); + } + Handler::RequestStream(sender) => { info!("REQUEST_STREAM {} cancelled!", sid); } - Handler::Channel((sender, c)) => { + Handler::RequestChannel(sender, c) => { info!("REQUEST_CHANNEL {} cancelled!", sid); } }; @@ -198,22 +202,23 @@ impl DuplexSocket { let mut senders = handlers.map.write().unwrap(); // fire event! match senders.remove(&sid).unwrap() { - Handler::Request(sender) => sender.send(Ok(input)).unwrap(), - Handler::Stream(sender) => { + Handler::ReqRR(sender) => sender.send(Ok(input)).unwrap(), + Handler::ResRR(c) => unreachable!(), + Handler::RequestStream(sender) => { if flag & frame::FLAG_NEXT != 0 { sender.send(input).unwrap(); } if flag & frame::FLAG_COMPLETE == 0 { - senders.insert(sid, Handler::Stream(sender)); + senders.insert(sid, Handler::RequestStream(sender)); } } - Handler::Channel((sender, cdl)) => { + Handler::RequestChannel(sender, cdl) => { // TODO: support channel if flag & frame::FLAG_NEXT != 0 { sender.send(input).unwrap(); } if flag & frame::FLAG_COMPLETE == 0 { - senders.insert(sid, Handler::Channel((sender, cdl))); + senders.insert(sid, Handler::RequestChannel(sender, cdl)); } } }; @@ -243,8 +248,25 @@ impl DuplexSocket { async fn on_request_response(&self, sid: u32, _flag: u16, input: Payload) { let responder = self.responder.clone(); let tx = self.tx.clone(); + + let canceller = Counter::new(2); + self.register_handler(sid, Handler::ResRR(canceller.clone())); + + // pick handler + let handlers = self.handlers.clone(); + tokio::spawn(async move { - let sending = match responder.request_response(input).await { + let result = responder.request_response(input).await; + if canceller.count_down() == 0 { + // cancelled + return; + } + + // unregister handler + let mut senders = handlers.map.write().unwrap(); + senders.remove(&sid); + + let sending = match result { Ok(it) => { let (d, m) = it.split(); let mut bu = frame::Payload::builder(sid, frame::FLAG_COMPLETE); @@ -297,7 +319,7 @@ impl DuplexSocket { let (sender, receiver) = mpsc::unbounded_channel::(); sender.send(first).unwrap(); let cdl = Counter::new(2); - self.register_handler(sid, Handler::Channel((sender, cdl.clone()))); + self.register_handler(sid, Handler::RequestChannel(sender, cdl.clone())); tokio::spawn(async move { // respond client channel let inputs: Flux = Box::pin(receiver); @@ -384,7 +406,7 @@ impl RSocket for DuplexSocket { let (tx, rx) = oneshot::channel::>(); let sid = self.seq.next(); // register handler - self.register_handler(sid, Handler::Request(tx)); + self.register_handler(sid, Handler::ReqRR(tx)); let sender = self.tx.clone(); tokio::spawn(async move { @@ -415,7 +437,7 @@ impl RSocket for DuplexSocket { let tx = self.tx.clone(); // register handler let (sender, receiver) = mpsc::unbounded_channel::(); - self.register_handler(sid, Handler::Stream(sender)); + self.register_handler(sid, Handler::RequestStream(sender)); tokio::spawn(async move { let (d, m) = input.split(); // crate stream frame @@ -439,7 +461,7 @@ impl RSocket for DuplexSocket { // register handler let (sender, receiver) = mpsc::unbounded_channel::(); let cdl = Counter::new(2); - self.register_handler(sid, Handler::Channel((sender, cdl.clone()))); + self.register_handler(sid, Handler::RequestChannel(sender, cdl.clone())); tokio::spawn(async move { let mut first = true; while let Some(it) = reqs.next().await { diff --git a/tests/clients.rs b/tests/clients.rs index abf0c7f..963d85c 100644 --- a/tests/clients.rs +++ b/tests/clients.rs @@ -28,6 +28,7 @@ async fn test_client() { #[tokio::main] #[test] +#[ignore] async fn test_request_response_err() { env_logger::builder().format_timestamp_millis().init(); let cli = RSocketFactory::connect() From a25cc0ef1f2b2511495fd4976b964c82e22a5518 Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Sun, 8 Dec 2019 12:57:40 +0800 Subject: [PATCH 04/10] performance tuning for request_response with canceller support. --- src/transport/mod.rs | 2 +- src/transport/socket.rs | 67 +++++++++++++++++++++++------------------ src/transport/spi.rs | 24 ++++++++++----- src/transport/tcp.rs | 2 +- src/x/client.rs | 2 +- src/x/server.rs | 2 +- 6 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/transport/mod.rs b/src/transport/mod.rs index 4c5bdda..160dea4 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -5,4 +5,4 @@ mod spi; pub(crate) mod tcp; pub(crate) use codec::RFrameCodec; pub(crate) use socket::DuplexSocket; -pub(crate) use spi::{Acceptor, Rx, Transport, Tx}; +pub(crate) use spi::*; diff --git a/src/transport/socket.rs b/src/transport/socket.rs index f78583c..ba38416 100644 --- a/src/transport/socket.rs +++ b/src/transport/socket.rs @@ -1,5 +1,5 @@ use super::misc::{self, Counter, StreamID}; -use super::spi::{Acceptor, Rx, Transport, Tx}; +use super::spi::*; use crate::errors::{ErrorKind, RSocketError, ERR_APPLICATION}; use crate::frame::{self, Body, Frame}; use crate::payload::{Payload, SetupPayload}; @@ -17,19 +17,14 @@ use std::result::Result; use std::sync::{Arc, Mutex, RwLock}; use tokio::net::TcpListener; use tokio::prelude::*; -use tokio::sync::oneshot::{Receiver, Sender}; -use tokio::sync::{mpsc, oneshot}; - -type Single = oneshot::Sender>; -type Multi = mpsc::UnboundedSender; -type MultiReceiver = mpsc::UnboundedReceiver; #[derive(Clone)] pub(crate) struct DuplexSocket { seq: StreamID, responder: Responder, - tx: Tx, + tx: Tx, handlers: Arc, + canceller: Tx, } #[derive(Clone)] @@ -39,10 +34,10 @@ struct Responder { #[derive(Debug)] enum Handler { - ReqRR(Single), + ReqRR(TxOnce>), ResRR(Counter), - RequestStream(Multi), - RequestChannel(Multi, Counter), + RequestStream(Tx), + RequestChannel(Tx, Counter), } #[derive(Debug)] @@ -51,13 +46,21 @@ struct Handlers { } impl DuplexSocket { - pub(crate) fn new(first_stream_id: u32, tx: Tx) -> DuplexSocket { - DuplexSocket { + pub(crate) async fn new(first_stream_id: u32, tx: Tx) -> DuplexSocket { + let (canceller_tx, canceller_rx) = new_tx_rx::(); + let ds = DuplexSocket { seq: StreamID::from(first_stream_id), tx, + canceller: canceller_tx, responder: Responder::new(), handlers: Arc::new(Handlers::new()), - } + }; + + let ds2 = ds.clone(); + tokio::spawn(async move { + ds2.loop_canceller(canceller_rx).await; + }); + ds } pub(crate) fn close(self) { @@ -84,13 +87,23 @@ impl DuplexSocket { self.tx.send(bu.build()).unwrap(); } + #[inline] fn register_handler(&self, sid: u32, handler: Handler) { let handlers: Arc = self.handlers.clone(); let mut senders = handlers.map.write().unwrap(); senders.insert(sid, handler); } - pub(crate) async fn event_loop(&self, acceptor: Acceptor, mut rx: Rx) { + pub(crate) async fn loop_canceller(&self, mut rx: Rx) { + // TODO: loop cancel + while let Some(sid) = rx.recv().await { + let handlers: Arc = self.handlers.clone(); + let mut senders = handlers.map.write().unwrap(); + senders.remove(&sid); + } + } + + pub(crate) async fn event_loop(&self, acceptor: Acceptor, mut rx: Rx) { while let Some(msg) = rx.recv().await { let sid = msg.get_stream_id(); let flag = msg.get_flag(); @@ -247,24 +260,21 @@ impl DuplexSocket { #[inline] async fn on_request_response(&self, sid: u32, _flag: u16, input: Payload) { let responder = self.responder.clone(); + let canceller = self.canceller.clone(); let tx = self.tx.clone(); - let canceller = Counter::new(2); - self.register_handler(sid, Handler::ResRR(canceller.clone())); - - // pick handler - let handlers = self.handlers.clone(); + let counter = Counter::new(2); + self.register_handler(sid, Handler::ResRR(counter.clone())); tokio::spawn(async move { let result = responder.request_response(input).await; - if canceller.count_down() == 0 { + if counter.count_down() == 0 { // cancelled return; } - // unregister handler - let mut senders = handlers.map.write().unwrap(); - senders.remove(&sid); + // async remove canceller + canceller.send(sid).unwrap(); let sending = match result { Ok(it) => { @@ -316,7 +326,7 @@ impl DuplexSocket { async fn on_request_channel(&self, sid: u32, flag: u16, first: Payload) { let responder = self.responder.clone(); let tx = self.tx.clone(); - let (sender, receiver) = mpsc::unbounded_channel::(); + let (sender, receiver) = new_tx_rx::(); sender.send(first).unwrap(); let cdl = Counter::new(2); self.register_handler(sid, Handler::RequestChannel(sender, cdl.clone())); @@ -403,7 +413,7 @@ impl RSocket for DuplexSocket { }) } fn request_response(&self, req: Payload) -> Mono> { - let (tx, rx) = oneshot::channel::>(); + let (tx, rx) = new_tx_rx_once::>(); let sid = self.seq.next(); // register handler self.register_handler(sid, Handler::ReqRR(tx)); @@ -436,7 +446,7 @@ impl RSocket for DuplexSocket { let sid = self.seq.next(); let tx = self.tx.clone(); // register handler - let (sender, receiver) = mpsc::unbounded_channel::(); + let (sender, receiver) = new_tx_rx::(); self.register_handler(sid, Handler::RequestStream(sender)); tokio::spawn(async move { let (d, m) = input.split(); @@ -459,7 +469,7 @@ impl RSocket for DuplexSocket { let sid = self.seq.next(); let tx = self.tx.clone(); // register handler - let (sender, receiver) = mpsc::unbounded_channel::(); + let (sender, receiver) = new_tx_rx::(); let cdl = Counter::new(2); self.register_handler(sid, Handler::RequestChannel(sender, cdl.clone())); tokio::spawn(async move { @@ -490,7 +500,6 @@ impl RSocket for DuplexSocket { error!("send REQUEST_CHANNEL failed: {}", e); } } - cdl.count_down(); let sending = frame::Payload::builder(sid, frame::FLAG_COMPLETE).build(); if let Err(e) = tx.send(sending) { error!("complete REQUEST_CHANNEL failed: {}", e); diff --git a/src/transport/spi.rs b/src/transport/spi.rs index f5f08a3..8a2724b 100644 --- a/src/transport/spi.rs +++ b/src/transport/spi.rs @@ -3,22 +3,32 @@ use crate::payload::SetupPayload; use crate::spi::RSocket; use std::future::Future; use std::sync::Arc; -use tokio::sync::mpsc::{Receiver, Sender, UnboundedReceiver, UnboundedSender}; +use tokio::sync::{mpsc, oneshot}; -pub type Tx = UnboundedSender; -pub type Rx = UnboundedReceiver; +pub(crate) type Tx = mpsc::UnboundedSender; +pub(crate) type Rx = mpsc::UnboundedReceiver; +pub(crate) type TxOnce = oneshot::Sender; +pub(crate) type RxOnce = oneshot::Receiver; + +pub(crate) fn new_tx_rx_once() -> (TxOnce, RxOnce) { + oneshot::channel() +} + +pub(crate) fn new_tx_rx() -> (Tx, Rx) { + mpsc::unbounded_channel() +} pub struct Transport { - tx: UnboundedSender, - rx: UnboundedReceiver, + tx: Tx, + rx: Rx, } impl Transport { - pub fn new(tx: Tx, rx: Rx) -> Transport { + pub fn new(tx: Tx, rx: Rx) -> Transport { Transport { tx, rx } } - pub fn split(self) -> (Tx, Rx) { + pub fn split(self) -> (Tx, Rx) { (self.tx, self.rx) } } diff --git a/src/transport/tcp.rs b/src/transport/tcp.rs index 5c218be..97534f6 100644 --- a/src/transport/tcp.rs +++ b/src/transport/tcp.rs @@ -15,7 +15,7 @@ pub fn connect(addr: &SocketAddr) -> TcpStream { TcpStream::from_std(origin).unwrap() } -pub async fn process(socket: TcpStream, mut inputs: Rx, outputs: Tx) { +pub async fn process(socket: TcpStream, mut inputs: Rx, outputs: Tx) { let (mut writer, mut reader) = Framed::new(socket, RFrameCodec).split(); tokio::spawn(async move { // loop read diff --git a/src/x/client.rs b/src/x/client.rs index 99181b8..c5cf48b 100644 --- a/src/x/client.rs +++ b/src/x/client.rs @@ -116,7 +116,7 @@ impl ClientBuilder { let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); tokio::spawn(async move { crate::transport::tcp::process(socket, snd_rx, rcv_tx).await }); - let duplex_socket = DuplexSocket::new(1, snd_tx.clone()); + let duplex_socket = DuplexSocket::new(1, snd_tx.clone()).await; let duplex_socket_clone = duplex_socket.clone(); tokio::spawn(async move { diff --git a/src/x/server.rs b/src/x/server.rs index eea4b65..1a2a965 100644 --- a/src/x/server.rs +++ b/src/x/server.rs @@ -81,7 +81,7 @@ impl ServerBuilder { ); let setuper = Arc::new(on_setup); let next_acceptor = move || Acceptor::Generate(setuper.clone()); - let ds = DuplexSocket::new(0, snd_tx.clone()); + let ds = DuplexSocket::new(0, snd_tx.clone()).await; tokio::spawn(async move { let acceptor = next_acceptor(); ds.event_loop(acceptor, rcv_rx).await; From db3b90435db3d3c4a31d33ea5c52bc3ace196f7c Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Sun, 8 Dec 2019 14:23:50 +0800 Subject: [PATCH 05/10] tuning for mutex: use tokio async/await mutex instead of std mutex. --- src/transport/socket.rs | 94 +++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 51 deletions(-) diff --git a/src/transport/socket.rs b/src/transport/socket.rs index ba38416..b1b979b 100644 --- a/src/transport/socket.rs +++ b/src/transport/socket.rs @@ -14,16 +14,17 @@ use std::future::Future; use std::pin::Pin; use std::ptr; use std::result::Result; -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::{Arc, RwLock}; use tokio::net::TcpListener; use tokio::prelude::*; +use tokio::sync::Mutex; #[derive(Clone)] pub(crate) struct DuplexSocket { seq: StreamID, responder: Responder, tx: Tx, - handlers: Arc, + handlers: Arc>>, canceller: Tx, } @@ -37,12 +38,7 @@ enum Handler { ReqRR(TxOnce>), ResRR(Counter), RequestStream(Tx), - RequestChannel(Tx, Counter), -} - -#[derive(Debug)] -struct Handlers { - map: RwLock>, + RequestChannel(Tx), } impl DuplexSocket { @@ -53,7 +49,7 @@ impl DuplexSocket { tx, canceller: canceller_tx, responder: Responder::new(), - handlers: Arc::new(Handlers::new()), + handlers: Arc::new(Mutex::new(HashMap::new())), }; let ds2 = ds.clone(); @@ -88,18 +84,16 @@ impl DuplexSocket { } #[inline] - fn register_handler(&self, sid: u32, handler: Handler) { - let handlers: Arc = self.handlers.clone(); - let mut senders = handlers.map.write().unwrap(); - senders.insert(sid, handler); + async fn register_handler(&self, sid: u32, handler: Handler) { + let mut handlers = self.handlers.lock().await; + (*handlers).insert(sid, handler); } + #[inline] pub(crate) async fn loop_canceller(&self, mut rx: Rx) { - // TODO: loop cancel while let Some(sid) = rx.recv().await { - let handlers: Arc = self.handlers.clone(); - let mut senders = handlers.map.write().unwrap(); - senders.remove(&sid); + let mut handlers = self.handlers.lock().await; + (*handlers).remove(&sid); } } @@ -166,10 +160,8 @@ impl DuplexSocket { #[inline] async fn on_error(&self, sid: u32, flag: u16, input: frame::Error) { // pick handler - let handlers = self.handlers.clone(); - let mut senders = handlers.map.write().unwrap(); - - if let Some(handler) = senders.remove(&sid) { + let mut handlers = self.handlers.lock().await; + if let Some(handler) = (*handlers).remove(&sid) { let kind = ErrorKind::Internal(input.get_code(), input.get_data_utf8()); let e = Err(RSocketError::from(kind)); match handler { @@ -183,11 +175,8 @@ impl DuplexSocket { #[inline] async fn on_cancel(&self, sid: u32, _flag: u16) { - // TODO: support cancel - // pick handler - let handlers = self.handlers.clone(); - let mut senders = handlers.map.write().unwrap(); - if let Some(handler) = senders.remove(&sid) { + let mut handlers = self.handlers.lock().await; + if let Some(handler) = (*handlers).remove(&sid) { let e = Err(RSocketError::from(ErrorKind::Cancelled())); match handler { Handler::ReqRR(sender) => { @@ -201,7 +190,7 @@ impl DuplexSocket { Handler::RequestStream(sender) => { info!("REQUEST_STREAM {} cancelled!", sid); } - Handler::RequestChannel(sender, c) => { + Handler::RequestChannel(sender) => { info!("REQUEST_CHANNEL {} cancelled!", sid); } }; @@ -210,11 +199,9 @@ impl DuplexSocket { #[inline] async fn on_payload(&self, sid: u32, flag: u16, input: Payload) { - // pick handler - let handlers = self.handlers.clone(); - let mut senders = handlers.map.write().unwrap(); + let mut handlers = self.handlers.lock().await; // fire event! - match senders.remove(&sid).unwrap() { + match (*handlers).remove(&sid).unwrap() { Handler::ReqRR(sender) => sender.send(Ok(input)).unwrap(), Handler::ResRR(c) => unreachable!(), Handler::RequestStream(sender) => { @@ -222,16 +209,16 @@ impl DuplexSocket { sender.send(input).unwrap(); } if flag & frame::FLAG_COMPLETE == 0 { - senders.insert(sid, Handler::RequestStream(sender)); + (*handlers).insert(sid, Handler::RequestStream(sender)); } } - Handler::RequestChannel(sender, cdl) => { + Handler::RequestChannel(sender) => { // TODO: support channel if flag & frame::FLAG_NEXT != 0 { sender.send(input).unwrap(); } if flag & frame::FLAG_COMPLETE == 0 { - senders.insert(sid, Handler::RequestChannel(sender, cdl)); + (*handlers).insert(sid, Handler::RequestChannel(sender)); } } }; @@ -264,7 +251,8 @@ impl DuplexSocket { let tx = self.tx.clone(); let counter = Counter::new(2); - self.register_handler(sid, Handler::ResRR(counter.clone())); + self.register_handler(sid, Handler::ResRR(counter.clone())) + .await; tokio::spawn(async move { let result = responder.request_response(input).await; @@ -328,8 +316,8 @@ impl DuplexSocket { let tx = self.tx.clone(); let (sender, receiver) = new_tx_rx::(); sender.send(first).unwrap(); - let cdl = Counter::new(2); - self.register_handler(sid, Handler::RequestChannel(sender, cdl.clone())); + self.register_handler(sid, Handler::RequestChannel(sender)) + .await; tokio::spawn(async move { // respond client channel let inputs: Flux = Box::pin(receiver); @@ -415,11 +403,15 @@ impl RSocket for DuplexSocket { fn request_response(&self, req: Payload) -> Mono> { let (tx, rx) = new_tx_rx_once::>(); let sid = self.seq.next(); - // register handler - self.register_handler(sid, Handler::ReqRR(tx)); - + let handlers = Arc::clone(&self.handlers); let sender = self.tx.clone(); tokio::spawn(async move { + { + // register handler + let mut map = handlers.lock().await; + (*map).insert(sid, Handler::ReqRR(tx)); + } + let (d, m) = req.split(); // crate request frame let mut bu = frame::RequestResponse::builder(sid, 0); @@ -447,8 +439,12 @@ impl RSocket for DuplexSocket { let tx = self.tx.clone(); // register handler let (sender, receiver) = new_tx_rx::(); - self.register_handler(sid, Handler::RequestStream(sender)); + let handlers = Arc::clone(&self.handlers); tokio::spawn(async move { + { + let mut map = handlers.lock().await; + (*map).insert(sid, Handler::RequestStream(sender)); + } let (d, m) = input.split(); // crate stream frame let mut bu = frame::RequestStream::builder(sid, 0); @@ -470,9 +466,13 @@ impl RSocket for DuplexSocket { let tx = self.tx.clone(); // register handler let (sender, receiver) = new_tx_rx::(); - let cdl = Counter::new(2); - self.register_handler(sid, Handler::RequestChannel(sender, cdl.clone())); + let handlers = Arc::clone(&self.handlers); tokio::spawn(async move { + { + let mut map = handlers.lock().await; + (*map).insert(sid, Handler::RequestChannel(sender)); + } + let mut first = true; while let Some(it) = reqs.next().await { let (d, m) = it.split(); @@ -509,14 +509,6 @@ impl RSocket for DuplexSocket { } } -impl Handlers { - fn new() -> Handlers { - Handlers { - map: RwLock::new(HashMap::new()), - } - } -} - impl From> for Responder { fn from(input: Box) -> Responder { Responder { From 58da718fe1c681108eee91c6b6eb30008f802816 Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Sun, 8 Dec 2019 14:34:49 +0800 Subject: [PATCH 06/10] upgrade tokio to 0.2.4 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a309e96..12ac9eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ url = "2.1.0" # reactor_rs = {git = "https://github.com/jjeffcaii/reactor-rust", branch = "develop"} [dependencies.tokio] -version = "0.2.2" +version = "0.2.4" default-features = false features = ["full"] From 8e7d276afb4c6172c4ee7ee0637f2ec0b9ee3932 Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Sun, 8 Dec 2019 15:46:14 +0800 Subject: [PATCH 07/10] Support reject setup. --- README.md | 4 +++- examples/echo/main.rs | 4 +++- examples/proxy/main.rs | 4 ++-- src/spi.rs | 2 +- src/transport/socket.rs | 36 +++++++++++++++++++++++++++++------- src/transport/spi.rs | 5 ++++- src/x/server.rs | 17 ++++++++++------- 7 files changed, 52 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 4965962..0ac8481 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,9 @@ async fn main() -> Result<(), Box> { .transport(&addr) .acceptor(|setup, _socket| { info!("accept setup: {:?}", setup); - Box::new(EchoRSocket) + Ok(Box::new(EchoRSocket)) + // Or you can reject setup + // Err(From::from("SETUP_NOT_ALLOW")) }) .serve() .await diff --git a/examples/echo/main.rs b/examples/echo/main.rs index 806d9d3..9becb20 100644 --- a/examples/echo/main.rs +++ b/examples/echo/main.rs @@ -16,7 +16,9 @@ async fn main() -> Result<(), Box> { .transport(&addr) .acceptor(|setup, _socket| { info!("accept setup: {:?}", setup); - Box::new(EchoRSocket) + Ok(Box::new(EchoRSocket)) + // Or you can reject setup + // Err(From::from("SETUP_NOT_ALLOW")) }) .on_start(|| info!("+++++++ echo server started! +++++++")) .serve() diff --git a/examples/proxy/main.rs b/examples/proxy/main.rs index 7fbe186..4224a05 100644 --- a/examples/proxy/main.rs +++ b/examples/proxy/main.rs @@ -16,7 +16,7 @@ async fn main() -> Result<(), Box> { RSocketFactory::receive() .acceptor(|setup, _sending_socket| { info!("incoming socket: setup={:?}", setup); - Box::new(block_on(async move { + Ok(Box::new(block_on(async move { RSocketFactory::connect() .acceptor(|| Box::new(EchoRSocket)) .setup(Payload::from("I'm Rust!")) @@ -24,7 +24,7 @@ async fn main() -> Result<(), Box> { .start() .await .unwrap() - })) + }))) }) .transport("tcp://127.0.0.1:7979") .serve() diff --git a/src/spi.rs b/src/spi.rs index 98f1a11..759418d 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -57,7 +57,7 @@ impl RSocket for EchoRSocket { } } -pub struct EmptyRSocket; +pub(crate) struct EmptyRSocket; impl EmptyRSocket { fn must_failed(&self) -> RSocketError { diff --git a/src/transport/socket.rs b/src/transport/socket.rs index b1b979b..42f9ec5 100644 --- a/src/transport/socket.rs +++ b/src/transport/socket.rs @@ -1,6 +1,6 @@ use super::misc::{self, Counter, StreamID}; use super::spi::*; -use crate::errors::{ErrorKind, RSocketError, ERR_APPLICATION}; +use crate::errors::{self, ErrorKind, RSocketError}; use crate::frame::{self, Body, Frame}; use crate::payload::{Payload, SetupPayload}; use crate::result::RSocketResult; @@ -103,7 +103,17 @@ impl DuplexSocket { let flag = msg.get_flag(); misc::debug_frame(false, &msg); match msg.get_body() { - Body::Setup(v) => self.on_setup(&acceptor, sid, flag, SetupPayload::from(v)), + Body::Setup(v) => { + if let Err(e) = self.on_setup(&acceptor, sid, flag, SetupPayload::from(v)) { + let errmsg = format!("{}", e); + let sending = frame::Error::builder(0, 0) + .set_code(errors::ERR_REJECT_SETUP) + .set_data(Bytes::from(errmsg)) + .build(); + self.tx.send(sending).unwrap(); + return; + } + } Body::Resume(v) => { // TODO: support resume } @@ -225,16 +235,28 @@ impl DuplexSocket { } #[inline] - fn on_setup(&self, acceptor: &Acceptor, sid: u32, flag: u16, setup: SetupPayload) { + fn on_setup( + &self, + acceptor: &Acceptor, + sid: u32, + flag: u16, + setup: SetupPayload, + ) -> Result<(), Box> { match acceptor { Acceptor::Simple(gen) => { self.responder.set(gen()); + Ok(()) } - Acceptor::Generate(gen) => { - self.responder.set(gen(setup, Box::new(self.clone()))); - } + Acceptor::Generate(gen) => match gen(setup, Box::new(self.clone())) { + Ok(it) => { + self.responder.set(it); + Ok(()) + } + Err(e) => Err(e), + }, Acceptor::Empty() => { self.responder.set(Box::new(EmptyRSocket)); + Ok(()) } } } @@ -277,7 +299,7 @@ impl DuplexSocket { bu.build() } Err(e) => frame::Error::builder(sid, 0) - .set_code(ERR_APPLICATION) + .set_code(errors::ERR_APPLICATION) .set_data(Bytes::from("TODO: should be error details")) .build(), }; diff --git a/src/transport/spi.rs b/src/transport/spi.rs index 8a2724b..5e74cd4 100644 --- a/src/transport/spi.rs +++ b/src/transport/spi.rs @@ -1,7 +1,9 @@ use crate::frame::Frame; use crate::payload::SetupPayload; use crate::spi::RSocket; +use std::error::Error; use std::future::Future; +use std::result::Result; use std::sync::Arc; use tokio::sync::{mpsc, oneshot}; @@ -33,7 +35,8 @@ impl Transport { } } -type FnAcceptorWithSetup = fn(SetupPayload, Box) -> Box; +pub type FnAcceptorWithSetup = + fn(SetupPayload, Box) -> Result, Box>; pub(crate) enum Acceptor { Simple(Arc Box>), diff --git a/src/x/server.rs b/src/x/server.rs index 1a2a965..f44a98a 100644 --- a/src/x/server.rs +++ b/src/x/server.rs @@ -3,19 +3,19 @@ use crate::errors::RSocketError; use crate::frame::{self, Frame}; use crate::payload::SetupPayload; use crate::spi::{EmptyRSocket, RSocket}; -use crate::transport::{Acceptor, DuplexSocket}; +use crate::transport::{Acceptor, DuplexSocket, FnAcceptorWithSetup}; use std::error::Error; use std::net::SocketAddr; +use std::result::Result; use std::sync::Arc; use tokio::net::TcpListener; use tokio::sync::mpsc; -type FnSetup = fn(SetupPayload, Box) -> Box; type FnStart = fn(); pub struct ServerBuilder { uri: Option, - on_setup: FnSetup, + on_setup: FnAcceptorWithSetup, start_handler: Option, } @@ -34,7 +34,7 @@ impl ServerBuilder { } } - pub fn acceptor(mut self, handler: FnSetup) -> Self { + pub fn acceptor(mut self, handler: FnAcceptorWithSetup) -> Self { self.on_setup = handler; self } @@ -64,7 +64,7 @@ impl ServerBuilder { #[inline] async fn serve_tcp( addr: SocketAddr, - on_setup: FnSetup, + on_setup: FnAcceptorWithSetup, on_start: Option, ) -> Result<(), Box> { let mut listener = TcpListener::bind(&addr).await.unwrap(); @@ -91,6 +91,9 @@ impl ServerBuilder { } #[inline] -fn on_setup_noop(_setup: SetupPayload, _socket: Box) -> Box { - Box::new(EmptyRSocket) +fn on_setup_noop( + _setup: SetupPayload, + _socket: Box, +) -> Result, Box> { + Ok(Box::new(EmptyRSocket)) } From cc71ca600466a55188d4c0d6c0ba439a69a69157 Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Sun, 15 Dec 2019 19:46:21 +0800 Subject: [PATCH 08/10] optimize unit test. --- examples/echo/main.rs | 2 +- examples/proxy/main.rs | 2 +- src/x/client.rs | 5 ++-- src/x/server.rs | 4 +-- src/x/uri.rs | 4 +-- tests/clients.rs | 66 ++++++++++++++++++++++++++++++------------ 6 files changed, 57 insertions(+), 26 deletions(-) diff --git a/examples/echo/main.rs b/examples/echo/main.rs index 9becb20..30e6a4a 100644 --- a/examples/echo/main.rs +++ b/examples/echo/main.rs @@ -7,7 +7,7 @@ use std::env; use std::error::Error; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<(), Box> { env_logger::builder().format_timestamp_millis().init(); let addr = env::args() .nth(1) diff --git a/examples/proxy/main.rs b/examples/proxy/main.rs index 4224a05..7f35a20 100644 --- a/examples/proxy/main.rs +++ b/examples/proxy/main.rs @@ -10,7 +10,7 @@ use rsocket_rust::prelude::*; use std::error::Error; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<(), Box> { env_logger::builder().format_timestamp_millis().init(); RSocketFactory::receive() diff --git a/src/x/client.rs b/src/x/client.rs index c5cf48b..aaeb952 100644 --- a/src/x/client.rs +++ b/src/x/client.rs @@ -94,7 +94,8 @@ impl ClientBuilder { self.responder = Some(acceptor); self } - pub async fn start(self) -> Result> { + + pub async fn start(self) -> Result> { // TODO: process error let uri = self.uri.unwrap(); match URI::parse(&uri) { @@ -111,7 +112,7 @@ impl ClientBuilder { addr: SocketAddr, responder: Option Box>, sb: SetupPayloadBuilder, - ) -> Result> { + ) -> Result> { let socket = transport::tcp::connect(&addr); let (rcv_tx, rcv_rx) = mpsc::unbounded_channel::(); let (snd_tx, snd_rx) = mpsc::unbounded_channel::(); diff --git a/src/x/server.rs b/src/x/server.rs index f44a98a..d33a26a 100644 --- a/src/x/server.rs +++ b/src/x/server.rs @@ -49,7 +49,7 @@ impl ServerBuilder { self } - pub async fn serve(self) -> Result<(), Box> { + pub async fn serve(self) -> Result<(), Box> { // TODO: process error let s = self.uri.unwrap(); match URI::parse(&s) { @@ -66,7 +66,7 @@ impl ServerBuilder { addr: SocketAddr, on_setup: FnAcceptorWithSetup, on_start: Option, - ) -> Result<(), Box> { + ) -> Result<(), Box> { let mut listener = TcpListener::bind(&addr).await.unwrap(); debug!("listening on: {}", addr); if let Some(it) = on_start { diff --git a/src/x/uri.rs b/src/x/uri.rs index f1dde88..956a285 100644 --- a/src/x/uri.rs +++ b/src/x/uri.rs @@ -15,7 +15,7 @@ pub(crate) enum URI { } impl URI { - pub(crate) fn parse(s: &str) -> Result> { + pub(crate) fn parse(s: &str) -> Result> { match Url::parse(s) { Ok(u) => Self::from_url(u), Err(e) => Err(Box::new(e)), @@ -23,7 +23,7 @@ impl URI { } #[inline] - fn from_url(u: Url) -> Result> { + fn from_url(u: Url) -> Result> { let domain = u.domain().unwrap_or("0.0.0.0"); let schema = u.scheme(); match schema.to_lowercase().as_ref() { diff --git a/tests/clients.rs b/tests/clients.rs index 963d85c..cbe9375 100644 --- a/tests/clients.rs +++ b/tests/clients.rs @@ -3,27 +3,57 @@ extern crate log; use futures::stream; use rsocket_rust::prelude::*; +use std::thread::sleep; +use std::time::Duration; +use tokio::runtime::Runtime; + +fn init() { + let _ = env_logger::builder() + .format_timestamp_millis() + .is_test(true) + .try_init(); +} -#[tokio::main] #[test] -#[ignore] -async fn test_client() { - env_logger::builder().init(); - let cli = RSocketFactory::connect() - .acceptor(|| Box::new(EchoRSocket)) - .transport("tcp://127.0.0.1:7878") - .setup(Payload::from("READY!")) - .mime_type("text/plain", "text/plain") - .start() - .await - .unwrap(); +fn test_client() { + init(); + + let server_runtime = Runtime::new().unwrap(); + + // spawn a server + server_runtime.spawn(async move { + RSocketFactory::receive() + .transport("tcp://127.0.0.1:7878") + .acceptor(|setup, _socket| { + info!("accept setup: {:?}", setup); + Ok(Box::new(EchoRSocket)) + }) + .on_start(|| info!("+++++++ echo server started! +++++++")) + .serve() + .await + }); + + sleep(Duration::from_millis(500)); + + let mut client_runtime = Runtime::new().unwrap(); + + client_runtime.block_on(async { + let cli = RSocketFactory::connect() + .acceptor(|| Box::new(EchoRSocket)) + .transport("tcp://127.0.0.1:7878") + .setup(Payload::from("READY!")) + .mime_type("text/plain", "text/plain") + .start() + .await + .unwrap(); - exec_metadata_push(&cli).await; - exec_fire_and_forget(&cli).await; - exec_request_response(&cli).await; - exec_request_stream(&cli).await; - exec_request_channel(&cli).await; - cli.close(); + exec_metadata_push(&cli).await; + exec_fire_and_forget(&cli).await; + exec_request_response(&cli).await; + exec_request_stream(&cli).await; + exec_request_channel(&cli).await; + cli.close(); + }); } #[tokio::main] From 7b8bcc68b7c6c4cecb2e4e9d5cece2f20335b688 Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Tue, 24 Dec 2019 19:46:08 +0800 Subject: [PATCH 09/10] bugfix: response payload of REQUEST_RESPONSE will be sent with NEXT|COMPLETE flag. --- src/transport/socket.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/transport/socket.rs b/src/transport/socket.rs index 42f9ec5..b52ebcb 100644 --- a/src/transport/socket.rs +++ b/src/transport/socket.rs @@ -289,7 +289,8 @@ impl DuplexSocket { let sending = match result { Ok(it) => { let (d, m) = it.split(); - let mut bu = frame::Payload::builder(sid, frame::FLAG_COMPLETE); + let mut bu = + frame::Payload::builder(sid, frame::FLAG_NEXT | frame::FLAG_COMPLETE); if let Some(b) = d { bu = bu.set_data(b); } From 5c79d97439b3ca9296454fc4a0bf0f5ba5ce0551 Mon Sep 17 00:00:00 2001 From: Jeffsky Date: Tue, 24 Dec 2019 20:00:29 +0800 Subject: [PATCH 10/10] upgrade dependencies. --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 12ac9eb..20505d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,14 +12,14 @@ description = "rsocket-rust is an implementation of the RSocket protocol in Rust [dependencies] matches = "0.1.8" log = "0.4.8" -bytes = "0.5.2" +bytes = "0.5.3" futures = "0.3.1" lazy_static = "1.4.0" url = "2.1.0" # reactor_rs = {git = "https://github.com/jjeffcaii/reactor-rust", branch = "develop"} [dependencies.tokio] -version = "0.2.4" +version = "0.2.6" default-features = false features = ["full"]