1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-27 18:02:58 +01:00

use bitflags for internal flags; use tokio 0.2

This commit is contained in:
Nikolay Kim 2019-12-05 13:11:56 +06:00
parent 6f41b80cb4
commit d49aca9595
5 changed files with 50 additions and 90 deletions

View File

@ -1,5 +1,9 @@
# Changes
## [0.2.0-alpha.3]
* Use tokio 0.2
* Fix low/high watermark for write/read buffers
## [0.2.0-alpha.2]

View File

@ -1,6 +1,6 @@
[package]
name = "actix-codec"
version = "0.2.0-alpha.2"
version = "0.2.0-alpha.3"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Utilities for encoding and decoding frames"
keywords = ["network", "framework", "async", "futures"]
@ -18,9 +18,10 @@ name = "actix_codec"
path = "src/lib.rs"
[dependencies]
bytes = "0.4.12"
bitflags = "1.2.1"
bytes = "0.5.2"
futures = "0.3.1"
pin-project = "0.4.5"
tokio-io = "=0.2.0-alpha.6"
tokio-codec = "=0.2.0-alpha.6"
pin-project = "0.4.6"
tokio = { version = "0.2.2", default-features=false }
tokio-util = { version = "0.2.0", default-features=false, features=["codec"] }
log = "0.4"

View File

@ -1,7 +1,7 @@
use bytes::{BufMut, Bytes, BytesMut};
use std::io;
use bytes::{Bytes, BytesMut};
use tokio_codec::{Decoder, Encoder};
use super::{Decoder, Encoder};
/// Bytes codec.
///
@ -14,7 +14,8 @@ impl Encoder for BytesCodec {
type Error = io::Error;
fn encode(&mut self, item: Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> {
dst.extend_from_slice(&item[..]);
dst.reserve(item.len());
dst.put(item);
Ok(())
}
}
@ -27,7 +28,8 @@ impl Decoder for BytesCodec {
if src.is_empty() {
Ok(None)
} else {
Ok(Some(src.take()))
let len = src.len();
Ok(Some(src.split_to(len)))
}
}
}

View File

@ -1,19 +1,22 @@
#![allow(deprecated)]
use std::fmt;
use std::io::{self};
use std::pin::Pin;
use std::task::{Context, Poll};
use std::{fmt, io};
use bytes::{BufMut, BytesMut};
use futures::{ready, Sink, Stream};
use pin_project::pin_project;
use tokio_codec::{Decoder, Encoder};
use tokio_io::{AsyncRead, AsyncWrite};
use crate::{AsyncRead, AsyncWrite, Decoder, Encoder};
const LW: usize = 1024;
const HW: usize = 8 * 1024;
const INITIAL_CAPACITY: usize = 8 * 1024;
bitflags::bitflags! {
struct Flags: u8 {
const EOF = 0b0001;
const READABLE = 0b0010;
}
}
/// A unified `Stream` and `Sink` interface to an underlying I/O object, using
/// the `Encoder` and `Decoder` traits to encode and decode frames.
@ -23,12 +26,9 @@ const INITIAL_CAPACITY: usize = 8 * 1024;
pub struct Framed<T, U> {
io: T,
codec: U,
eof: bool,
is_readable: bool,
flags: Flags,
read_buf: BytesMut,
write_buf: BytesMut,
write_lw: usize,
write_hw: usize,
}
impl<T, U> Framed<T, U>
@ -57,27 +57,9 @@ where
Framed {
io,
codec,
eof: false,
is_readable: false,
read_buf: BytesMut::with_capacity(INITIAL_CAPACITY),
flags: Flags::empty(),
read_buf: BytesMut::with_capacity(HW),
write_buf: BytesMut::with_capacity(HW),
write_lw: LW,
write_hw: HW,
}
}
/// Same as `Framed::new()` with ability to specify write buffer low/high capacity watermarks.
pub fn new_with_caps(io: T, codec: U, lw: usize, hw: usize) -> Framed<T, U> {
debug_assert!((lw < hw) && hw != 0);
Framed {
io,
codec,
eof: false,
is_readable: false,
read_buf: BytesMut::with_capacity(INITIAL_CAPACITY),
write_buf: BytesMut::with_capacity(hw),
write_lw: lw,
write_hw: hw,
}
}
}
@ -108,11 +90,8 @@ impl<T, U> Framed<T, U> {
Framed {
io: parts.io,
codec: parts.codec,
eof: false,
is_readable: false,
flags: parts.flags,
write_buf: parts.write_buf,
write_lw: parts.write_buf_lw,
write_hw: parts.write_buf_hw,
read_buf: parts.read_buf,
}
}
@ -154,7 +133,7 @@ impl<T, U> Framed<T, U> {
/// Check if write buffer is full.
pub fn is_write_buf_full(&self) -> bool {
self.write_buf.len() >= self.write_hw
self.write_buf.len() >= HW
}
/// Consumes the `Frame`, returning its underlying I/O stream.
@ -169,14 +148,11 @@ impl<T, U> Framed<T, U> {
/// Consume the `Frame`, returning `Frame` with different codec.
pub fn into_framed<U2>(self, codec: U2) -> Framed<T, U2> {
Framed {
io: self.io,
codec,
eof: self.eof,
is_readable: self.is_readable,
io: self.io,
flags: self.flags,
read_buf: self.read_buf,
write_buf: self.write_buf,
write_lw: self.write_lw,
write_hw: self.write_hw,
}
}
@ -188,12 +164,9 @@ impl<T, U> Framed<T, U> {
Framed {
io: f(self.io),
codec: self.codec,
eof: self.eof,
is_readable: self.is_readable,
flags: self.flags,
read_buf: self.read_buf,
write_buf: self.write_buf,
write_lw: self.write_lw,
write_hw: self.write_hw,
}
}
@ -205,12 +178,9 @@ impl<T, U> Framed<T, U> {
Framed {
io: self.io,
codec: f(self.codec),
eof: self.eof,
is_readable: self.is_readable,
flags: self.flags,
read_buf: self.read_buf,
write_buf: self.write_buf,
write_lw: self.write_lw,
write_hw: self.write_hw,
}
}
@ -224,11 +194,9 @@ impl<T, U> Framed<T, U> {
FramedParts {
io: self.io,
codec: self.codec,
flags: self.flags,
read_buf: self.read_buf,
write_buf: self.write_buf,
write_buf_lw: self.write_lw,
write_buf_hw: self.write_hw,
_priv: (),
}
}
}
@ -241,8 +209,8 @@ impl<T, U> Framed<T, U> {
U: Encoder,
{
let remaining = self.write_buf.remaining_mut();
if remaining < self.write_lw {
self.write_buf.reserve(self.write_hw - remaining);
if remaining < LW {
self.write_buf.reserve(HW - remaining);
}
self.codec.encode(item, &mut self.write_buf)?;
@ -251,7 +219,7 @@ impl<T, U> Framed<T, U> {
/// Check if framed is able to write more data
pub fn is_ready(&self) -> bool {
self.write_buf.len() < self.write_hw
self.write_buf.len() < HW
}
pub fn next_item(&mut self, cx: &mut Context<'_>) -> Poll<Option<Result<U::Item, U::Error>>>
@ -266,8 +234,8 @@ impl<T, U> Framed<T, U> {
// readable, it can be assumed that the decoder will never become
// readable again, at which point the stream is terminated.
if self.is_readable {
if self.eof {
if self.flags.contains(Flags::READABLE) {
if self.flags.contains(Flags::EOF) {
match self.codec.decode_eof(&mut self.read_buf) {
Ok(Some(frame)) => return Poll::Ready(Some(Ok(frame))),
Ok(None) => return Poll::Ready(None),
@ -288,10 +256,10 @@ impl<T, U> Framed<T, U> {
}
}
self.is_readable = false;
self.flags.remove(Flags::READABLE);
}
assert!(!self.eof);
debug_assert!(!self.flags.contains(Flags::EOF));
// Otherwise, try to read more data and try again. Make sure we've got room
let remaining = self.read_buf.remaining_mut();
@ -307,9 +275,9 @@ impl<T, U> Framed<T, U> {
};
if cnt == 0 {
self.eof = true;
self.flags.insert(Flags::EOF);
}
self.is_readable = true;
self.flags.insert(Flags::READABLE);
}
}
@ -441,15 +409,7 @@ pub struct FramedParts<T, U> {
/// A buffer with unprocessed data which are not written yet.
pub write_buf: BytesMut,
/// A buffer low watermark capacity
pub write_buf_lw: usize,
/// A buffer high watermark capacity
pub write_buf_hw: usize,
/// This private field allows us to add additional fields in the future in a
/// backwards compatible way.
_priv: (),
flags: Flags,
}
impl<T, U> FramedParts<T, U> {
@ -458,11 +418,9 @@ impl<T, U> FramedParts<T, U> {
FramedParts {
io,
codec,
flags: Flags::empty(),
read_buf: BytesMut::new(),
write_buf: BytesMut::new(),
write_buf_lw: LW,
write_buf_hw: HW,
_priv: (),
}
}
@ -472,10 +430,8 @@ impl<T, U> FramedParts<T, U> {
io,
codec,
read_buf,
flags: Flags::empty(),
write_buf: BytesMut::new(),
write_buf_lw: LW,
write_buf_hw: HW,
_priv: (),
}
}
}

View File

@ -6,9 +6,6 @@
//!
//! [`AsyncRead`]: #
//! [`AsyncWrite`]: #
//! [`Sink`]: #
//! [`Stream`]: #
//! [transports]: #
#![deny(rust_2018_idioms, warnings)]
#![allow(clippy::type_complexity)]
@ -18,5 +15,5 @@ mod framed;
pub use self::bcodec::BytesCodec;
pub use self::framed::{Framed, FramedParts};
pub use tokio_codec::{Decoder, Encoder};
pub use tokio_io::{AsyncRead, AsyncWrite};
pub use tokio::io::{AsyncRead, AsyncWrite};
pub use tokio_util::codec::{Decoder, Encoder};