Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No std #516

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ fxhash = "0.2.1"
fail = { version = "0.4", optional = true }
getset = "0.1.1"
protobuf = "2"
thiserror = "1.0"
thiserror = { version = "1.0", default-features = false }
raft-proto = { path = "proto", version = "0.7.0", default-features = false }
rand = "0.8"
slog = "2.2"
slog-envlogger = { version = "2.1.0", optional = true }
slog-stdlog = { version = "4", optional = true }
slog-term = { version = "2.4.0", optional = true }
spin = { version = "0.9.8" }

[dev-dependencies]
criterion = "0.3"
Expand Down
10 changes: 9 additions & 1 deletion src/confchange/changer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.

extern crate alloc;

use alloc::borrow::ToOwned;
use alloc::format;
use alloc::vec;
use alloc::vec::Vec;

use crate::eraftpb::{ConfChangeSingle, ConfChangeType};
use crate::tracker::{Configuration, ProgressMap, ProgressTracker};
use crate::{Error, Result};
Expand Down Expand Up @@ -114,7 +121,8 @@ impl Changer<'_> {
cfg
)));
}
cfg.learners.extend(cfg.learners_next.drain());
cfg.learners.extend(cfg.learners_next.iter());
cfg.learners_next.clear();

for id in &*cfg.voters.outgoing {
if !cfg.voters.incoming.contains(id) && !cfg.learners.contains(id) {
Expand Down
4 changes: 4 additions & 0 deletions src/confchange/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// TODO: remove following line
#![allow(dead_code)]

extern crate alloc;

use alloc::vec::Vec;

use super::changer::Changer;
use crate::eraftpb::{ConfChangeSingle, ConfChangeType, ConfState};
use crate::tracker::ProgressTracker;
Expand Down
5 changes: 5 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate alloc;

use alloc::borrow::ToOwned;
use alloc::format;

pub use super::read_only::{ReadOnlyOption, ReadState};
use super::util::NO_LIMIT;
use super::{
Expand Down
143 changes: 98 additions & 45 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,62 +1,98 @@
// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
use thiserror::Error;
extern crate alloc;

use alloc::string::String;
use core::fmt;

/// The base error type for raft
#[derive(Debug, Error)]
#[derive(Debug)]
pub enum Error {
/// An IO error occurred
#[error("{0}")]
Io(#[from] std::io::Error),
// /// An IO error occurred
// #[error("An io error occured")]
// Io(#[from] std::io::Error),
/// A storage error occurred.
#[error("{0}")]
Store(#[from] StorageError),
Store(StorageError),
/// Raft cannot step the local message.
#[error("raft: cannot step raft local message")]
StepLocalMsg,
/// The raft peer is not found and thus cannot step.
#[error("raft: cannot step as peer not found")]
StepPeerNotFound,
/// The proposal of changes was dropped.
#[error("raft: proposal dropped")]
ProposalDropped,
/// The configuration is invalid.
#[error("{0}")]
ConfigInvalid(String),
/// A protobuf message codec failed in some manner.
#[error("protobuf codec error {0:?}")]
CodecError(#[from] protobuf::ProtobufError),
CodecError(protobuf::ProtobufError),
/// The node exists, but should not.
#[error("The node {id} already exists in the {set} set.")]
Exists {
/// The node id.
id: u64,
/// The node set.
set: &'static str,
},
/// The node does not exist, but should.
#[error("The node {id} is not in the {set} set.")]
NotExists {
/// The node id.
id: u64,
/// The node set.
set: &'static str,
},
/// ConfChange proposal is invalid.
#[error("{0}")]
ConfChangeError(String),
/// The request snapshot is dropped.
#[error("raft: request snapshot dropped")]
RequestSnapshotDropped,
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Store(ref e) => write!(f, "{}", e),
Error::StepLocalMsg => write!(f, "raft: cannot step raft local message"),
Error::StepPeerNotFound => write!(f, "raft: cannot step as peer not found"),
Error::ProposalDropped => write!(f, "raft: proposal dropped"),
Error::ConfigInvalid(ref m) => write!(f, "{}", m),
Error::CodecError(ref e) => write!(f, "protobuf codec error {0:?}", e),
Error::Exists { id, set } => {
write!(f, "The node {id} already exists in the {set} set.")
}
Error::NotExists { id, set } => {
write!(f, "The node {id} is not in the {set} set.")
}
Error::ConfChangeError(ref m) => write!(f, "{}", m),
Error::RequestSnapshotDropped => write!(f, "raft: request snapshot dropped"),
}
}
}

impl core::error::Error for Error {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match *self {
Error::Store(ref e) => Some(e),
Error::CodecError(ref e) => Some(e),
_ => None,
}
}
}

impl From<StorageError> for Error {
fn from(err: StorageError) -> Error {
Error::Store(err)
}
}

impl From<protobuf::ProtobufError> for Error {
fn from(err: protobuf::ProtobufError) -> Error {
Error::CodecError(err)
}
}

impl PartialEq for Error {
#[cfg_attr(feature = "cargo-clippy", allow(clippy::match_same_arms))]
fn eq(&self, other: &Error) -> bool {
match (self, other) {
(Error::StepPeerNotFound, Error::StepPeerNotFound) => true,
(Error::ProposalDropped, Error::ProposalDropped) => true,
(Error::Store(ref e1), Error::Store(ref e2)) => e1 == e2,
(Error::Io(ref e1), Error::Io(ref e2)) => e1.kind() == e2.kind(),
// (Error::Io(ref e1), Error::Io(ref e2)) => e1.kind() == e2.kind(),
(Error::StepLocalMsg, Error::StepLocalMsg) => true,
(Error::ConfigInvalid(ref e1), Error::ConfigInvalid(ref e2)) => e1 == e2,
(Error::RequestSnapshotDropped, Error::RequestSnapshotDropped) => true,
Expand All @@ -67,26 +103,43 @@ impl PartialEq for Error {
}

/// An error with the storage.
#[derive(Debug, Error)]
#[derive(Debug)]
pub enum StorageError {
/// The storage was compacted and not accessible
#[error("log compacted")]
Compacted,
/// The log is not available.
#[error("log unavailable")]
Unavailable,
/// The log is being fetched.
#[error("log is temporarily unavailable")]
LogTemporarilyUnavailable,
/// The snapshot is out of date.
#[error("snapshot out of date")]
SnapshotOutOfDate,
/// The snapshot is being created.
#[error("snapshot is temporarily unavailable")]
SnapshotTemporarilyUnavailable,
/// Some other error occurred.
#[error("unknown error {0}")]
Other(#[from] Box<dyn std::error::Error + Sync + Send>),
// /// Some other error occurred.
// #[error("unknown error {0}")]
// Other(#[from] Box<dyn core::error::Error + Sync + Send>),
}

impl fmt::Display for StorageError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
StorageError::Compacted => write!(f, "log compacted"),
StorageError::Unavailable => write!(f, "log unavailable"),
StorageError::LogTemporarilyUnavailable => write!(f, "log is temporarily unavailable"),
StorageError::SnapshotOutOfDate => write!(f, "snapshot out of date"),
StorageError::SnapshotTemporarilyUnavailable => {
write!(f, "snapshot is temporarily unavailable")
}
}
}
}

impl core::error::Error for StorageError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match *self {
_ => None,
}
}
}

impl PartialEq for StorageError {
Expand All @@ -113,13 +166,13 @@ impl PartialEq for StorageError {
}

/// A result type that wraps up the raft errors.
pub type Result<T> = std::result::Result<T, Error>;
pub type Result<T> = core::result::Result<T, Error>;

#[allow(clippy::eq_op)]
#[cfg(test)]
mod tests {
use super::*;
use std::io;
// use std::io;

#[test]
fn test_error_equal() {
Expand All @@ -128,14 +181,14 @@ mod tests {
Error::Store(StorageError::Compacted),
Error::Store(StorageError::Compacted)
);
assert_eq!(
Error::Io(io::Error::new(io::ErrorKind::UnexpectedEof, "oh no!")),
Error::Io(io::Error::new(io::ErrorKind::UnexpectedEof, "oh yes!"))
);
assert_ne!(
Error::Io(io::Error::new(io::ErrorKind::NotFound, "error")),
Error::Io(io::Error::new(io::ErrorKind::BrokenPipe, "error"))
);
// assert_eq!(
// Error::Io(io::Error::new(io::ErrorKind::UnexpectedEof, "oh no!")),
// Error::Io(io::Error::new(io::ErrorKind::UnexpectedEof, "oh yes!"))
// );
// assert_ne!(
// Error::Io(io::Error::new(io::ErrorKind::NotFound, "error")),
// Error::Io(io::Error::new(io::ErrorKind::BrokenPipe, "error"))
// );
assert_eq!(Error::StepLocalMsg, Error::StepLocalMsg);
assert_eq!(
Error::ConfigInvalid(String::from("config error")),
Expand All @@ -145,10 +198,10 @@ mod tests {
Error::ConfigInvalid(String::from("config error")),
Error::ConfigInvalid(String::from("other error"))
);
assert_eq!(
Error::from(io::Error::new(io::ErrorKind::Other, "oh no!")),
Error::from(io::Error::new(io::ErrorKind::Other, "oh yes!"))
);
// assert_eq!(
// Error::from(io::Error::new(io::ErrorKind::Other, "oh no!")),
// Error::from(io::Error::new(io::ErrorKind::Other, "oh yes!"))
// );
assert_ne!(
Error::StepPeerNotFound,
Error::Store(StorageError::Compacted)
Expand All @@ -168,9 +221,9 @@ mod tests {
StorageError::SnapshotTemporarilyUnavailable
);
assert_ne!(StorageError::Compacted, StorageError::Unavailable);
assert_ne!(
StorageError::Other(Box::new(StorageError::Unavailable)),
StorageError::Unavailable
);
// assert_ne!(
// StorageError::Other(Box::new(StorageError::Unavailable)),
// StorageError::Unavailable
// );
}
}
56 changes: 30 additions & 26 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,10 @@ before taking old, removed peers offline.
// We use `default` method a lot to be support prost and rust-protobuf at the
// same time. And reassignment can be optimized by compiler.
#![allow(clippy::field_reassign_with_default)]
#![cfg_attr(not(test), no_std)]
#![feature(error_in_core)]

extern crate alloc;

macro_rules! fatal {
($logger:expr, $msg:expr) => {{
Expand Down Expand Up @@ -574,31 +578,31 @@ pub mod prelude {
/// Currently, this is a `log` adaptor behind a `Once` to ensure there is no clobbering.
#[cfg(any(test, feature = "default-logger"))]
pub fn default_logger() -> slog::Logger {
use slog::{o, Drain};
use std::sync::{Mutex, Once};

static LOGGER_INITIALIZED: Once = Once::new();
static mut LOGGER: Option<slog::Logger> = None;

let logger = unsafe {
LOGGER_INITIALIZED.call_once(|| {
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::CompactFormat::new(decorator).build();
let drain = slog_envlogger::new(drain);
LOGGER = Some(slog::Logger::root(Mutex::new(drain).fuse(), o!()));
});
LOGGER.as_ref().unwrap()
};
if let Some(case) = std::thread::current()
.name()
.and_then(|v| v.split(':').last())
{
logger.new(o!("case" => case.to_string()))
} else {
logger.new(o!())
}
use slog::o;
// use std::sync::{Mutex, Once};

// static LOGGER_INITIALIZED: Once = Once::new();
// static mut LOGGER: Option<slog::Logger> = None;

// let logger = unsafe {
// LOGGER_INITIALIZED.call_once(|| {
// let decorator = slog_term::TermDecorator::new().build();
// let drain = slog_term::CompactFormat::new(decorator).build();
// let drain = slog_envlogger::new(drain);
// LOGGER = Some(slog::Logger::root(Mutex::new(drain).fuse(), o!()));
// });
// LOGGER.as_ref().unwrap()
// };
// if let Some(case) = std::thread::current()
// .name()
// .and_then(|v| v.split(':').last())
// {
// logger.new(o!("case" => case.to_string()))
// } else {
slog::Logger::root(slog::Discard, o!())
// }
}

type DefaultHashBuilder = std::hash::BuildHasherDefault<fxhash::FxHasher>;
type HashMap<K, V> = std::collections::HashMap<K, V, DefaultHashBuilder>;
type HashSet<K> = std::collections::HashSet<K, DefaultHashBuilder>;
// type DefaultHashBuilder = core::hash::BuildHasherDefault<fxhash::FxHasher>;
type HashMap<K, V> = alloc::collections::btree_map::BTreeMap<K, V>;
type HashSet<K> = alloc::collections::btree_set::BTreeSet<K>;
5 changes: 5 additions & 0 deletions src/log_unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate alloc;

use alloc::vec;
use alloc::vec::Vec;

use crate::eraftpb::{Entry, Snapshot};
use crate::util::entry_approximate_size;
use slog::Logger;
Expand Down
Loading