diff --git a/.gitignore b/.gitignore index c4f2457f7..1184afb45 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,6 @@ tmp harness/target Cargo.lock +rust-toolchain *.rs.bk *.rs.fmt diff --git a/.travis.yml b/.travis.yml index 487bf79c0..400d6844c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ matrix: - rustup component add clippy-preview before_script: - cargo fmt --all -- --check - - cargo clippy --all -- -D clippy + - cargo clippy --all -- -D clippy::all # Since many users will use nightlies, also test that. - rust: nightly diff --git a/Cargo.toml b/Cargo.toml index 2d850bd04..30ef3822b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,16 +10,25 @@ homepage = "https://github.com/pingcap/raft-rs" documentation = "https://docs.rs/raft" description = "The rust language implementation of Raft algorithm." categories = ["algorithms", "database-implementations"] +edition = "2018" +build = "build.rs" + +[build-dependencies] +protoc-rust = "~2.0-2.2" +protoc-grpcio = "0.3.1" +regex = "1.1" [features] -default = [] +default = ["lib-rust-protobuf"] +lib-rust-protobuf = ["protobuf"] +regenerate = [] # Enable failpoints failpoint = ["fail"] # Make sure to synchronize updates with Harness. [dependencies] log = ">0.2" -protobuf = "~2.0-2.2" +protobuf = { version = "~2.0-2.2", optional = true } quick-error = "1.2.2" rand = "0.5.4" hashbrown = "0.1" diff --git a/benches/benches.rs b/benches/benches.rs index ea2be50a0..b21fba329 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -1,10 +1,6 @@ #![allow(dead_code)] // Due to criterion we need this to avoid warnings. #![cfg_attr(feature = "cargo-clippy", allow(clippy::let_and_return))] // Benches often artificially return values. Allow it. -extern crate criterion; -extern crate env_logger; -extern crate raft; - use criterion::Criterion; use std::time::Duration; diff --git a/benches/suites/progress_set.rs b/benches/suites/progress_set.rs index 3c7b4bcc0..bf310a63a 100644 --- a/benches/suites/progress_set.rs +++ b/benches/suites/progress_set.rs @@ -1,6 +1,6 @@ +use crate::DEFAULT_RAFT_SETS; use criterion::{Bencher, Criterion}; use raft::{Progress, ProgressSet}; -use DEFAULT_RAFT_SETS; pub fn bench_progress_set(c: &mut Criterion) { bench_progress_set_new(c); diff --git a/benches/suites/raft.rs b/benches/suites/raft.rs index 67214f30e..e72ecaef5 100644 --- a/benches/suites/raft.rs +++ b/benches/suites/raft.rs @@ -1,6 +1,6 @@ +use crate::DEFAULT_RAFT_SETS; use criterion::{Bencher, Criterion}; use raft::{storage::MemStorage, Config, Raft}; -use DEFAULT_RAFT_SETS; pub fn bench_raft(c: &mut Criterion) { bench_raft_new(c); diff --git a/build.rs b/build.rs new file mode 100644 index 000000000..ab0c063ce --- /dev/null +++ b/build.rs @@ -0,0 +1,170 @@ +// Copyright 2019 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +extern crate regex; + +use regex::Regex; +use std::fs::read_dir; +use std::fs::File; +use std::io::{Read, Write}; +use std::process::Command; +use std::{env, str}; + +fn main() { + // This build script creates files in the `src` directory. Since that is + // outside Cargo's OUT_DIR it will cause an error when this crate is used + // as a dependency. Therefore, the user must opt-in to regenerating the + // Rust files. + if env::var_os("CARGO_FEATURE_REGENERATE").is_none() { + println!("cargo:rerun-if-changed=build.rs"); + return; + } + + let file_names: Vec<_> = read_dir("proto") + .expect("Couldn't read proto directory") + .map(|e| { + format!( + "proto/{}", + e.expect("Couldn't list file").file_name().to_string_lossy() + ) + }) + .collect(); + let file_names: Vec<_> = file_names.iter().map(|s| &**s).collect(); + + for f in &file_names { + println!("cargo:rerun-if-changed={}", f); + } + + match BufferLib::from_env_vars() { + BufferLib::Prost => { + unimplemented!("Prost support is not yet implemented"); + } + + BufferLib::Protobuf => { + check_protoc_version(); + + generate_protobuf_files(file_names); + let mod_names: Vec<_> = read_dir("src/rsprotobuf") + .expect("Couldn't read src directory") + .filter_map(|e| { + let file_name = e.expect("Couldn't list file").file_name(); + file_name + .to_string_lossy() + .split(".rs") + .next() + .map(|n| n.to_owned()) + }) + .collect(); + replace_read_unknown_fields(&mod_names); + generate_protobuf_rs(&mod_names); + } + } +} + +#[derive(Eq, PartialEq)] +enum BufferLib { + Prost, + Protobuf, +} + +impl BufferLib { + fn from_env_vars() -> BufferLib { + match ( + env::var_os("CARGO_FEATURE_LIB_PROST"), + env::var_os("CARGO_FEATURE_LIB_RUST_PROTOBUF"), + ) { + (Some(_), Some(_)) | (None, None) => { + panic!("You must use exactly one of `lib-rust-protobuf` and `lib-prost` features") + } + (Some(_), _) => BufferLib::Prost, + (_, Some(_)) => BufferLib::Protobuf, + } + } +} + +fn check_protoc_version() { + let ver_re = Regex::new(r"([0-9]+)\.([0-9]+)\.[0-9]").unwrap(); + let ver = Command::new("protoc") + .arg("--version") + .output() + .expect("Program `protoc` not installed (is it in PATH?)."); + let caps = ver_re + .captures(str::from_utf8(&ver.stdout).unwrap()) + .unwrap(); + let major = caps.get(1).unwrap().as_str().parse::().unwrap(); + let minor = caps.get(2).unwrap().as_str().parse::().unwrap(); + if major == 3 && minor < 1 || major < 3 { + panic!( + "Invalid version of protoc (required 3.1.x, get {}.{}.x).", + major, minor, + ); + } +} + +fn generate_protobuf_files(file_names: Vec<&str>) { + protoc_rust::run(protoc_rust::Args { + out_dir: "src/rsprotobuf", + input: &file_names, + includes: &["proto", "include"], + customize: protoc_rust::Customize { + ..Default::default() + }, + }) + .unwrap(); + + protoc_grpcio::compile_grpc_protos(file_names, &["proto", "include"], "src/rsprotobuf") + .unwrap(); +} + +// Use the old way to read protobuf enums. +// FIXME: Remove this once stepancheg/rust-protobuf#233 is resolved. +fn replace_read_unknown_fields(mod_names: &[String]) { + let regex = + Regex::new(r"::protobuf::rt::read_proto3_enum_with_unknown_fields_into\(([^,]+), ([^,]+), &mut ([^,]+), [^\)]+\)\?").unwrap(); + for mod_name in mod_names { + let file_name = &format!("src/rsprotobuf/{}.rs", mod_name); + + let mut text = String::new(); + { + let mut f = File::open(file_name).unwrap(); + f.read_to_string(&mut text) + .expect("Couldn't read source file"); + } + + let text = regex.replace_all( + &text, + "if $1 == ::protobuf::wire_format::WireTypeVarint {\ + $3 = $2.read_enum()?;\ + } else {\ + return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));\ + }", + ); + let mut out = File::create(file_name).unwrap(); + out.write_all(text.as_bytes()) + .expect("Could not write source file"); + } +} + +fn generate_protobuf_rs(mod_names: &[String]) { + let mut text = "".to_owned(); + + for mod_name in mod_names { + text.push_str("pub mod "); + text.push_str(mod_name); + text.push_str(";\n"); + } + + let mut lib = File::create("src/rsprotobuf.rs").expect("Could not create rsprotobuf.rs"); + lib.write_all(text.as_bytes()) + .expect("Could not write rsprotobuf.rs"); +} diff --git a/examples/five_mem_node/main.rs b/examples/five_mem_node/main.rs index 34530da86..92c214f7d 100644 --- a/examples/five_mem_node/main.rs +++ b/examples/five_mem_node/main.rs @@ -12,10 +12,7 @@ // limitations under the License. #[macro_use] extern crate log; -extern crate env_logger; -extern crate protobuf; -extern crate raft; -extern crate regex; +use env_logger; use std::collections::{HashMap, VecDeque}; use std::sync::mpsc::{self, Receiver, Sender, SyncSender, TryRecvError}; diff --git a/examples/single_mem_node/main.rs b/examples/single_mem_node/main.rs index 2dc002f11..72cdd3553 100644 --- a/examples/single_mem_node/main.rs +++ b/examples/single_mem_node/main.rs @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate raft; +use raft; use std::collections::HashMap; use std::sync::mpsc::{self, RecvTimeoutError}; @@ -21,7 +21,7 @@ use std::time::{Duration, Instant}; use raft::prelude::*; use raft::storage::MemStorage; -type ProposeCallback = Box; +type ProposeCallback = Box; enum Msg { Propose { diff --git a/generate-proto.sh b/generate-proto.sh deleted file mode 100755 index ebe10c8cc..000000000 --- a/generate-proto.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -protoc proto/eraftpb.proto --rust_out=src/ -# TODO: remove this once stepancheg/rust-protobuf#233 is resolved. -python <) { + Other(err: Box) { from() cause(err.as_ref()) description(err.description()) diff --git a/src/lib.rs b/src/lib.rs index 281844197..44a3e1613 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -361,6 +361,23 @@ This process is a two-phase process, during the midst of it the peer group's lea active), it is very important to wait until the entire peer group has exited the transition phase before taking old, removed peers offline. +## Protocal-buffer libraries support + +We're storing Message with protocal-buffer, while there're multiple Rust protocal-buffer +libraries. We support two protocal-buffer libraries via features. You need to choose +exactly one from prost and rust-protobuf (default). + +### rust-protobuf + +This is enabled by default and can be explicitly enabled via `lib-rust-protobuf` feature. +The generated protobuf struct, `eraftpb::Message`, will be included in the project if +`lib-rust-protobuf` is enabled. This means you don't need to install `protoc` to compile +the `.proto` files. If you really want to do a regeneration, enable `regenerate` feature. + +### prost + +It's a work-in-progress. + */ #![deny(clippy::all)] @@ -369,22 +386,23 @@ before taking old, removed peers offline. #[cfg(feature = "failpoint")] #[macro_use] extern crate fail; -#[cfg(test)] -extern crate harness; -extern crate hashbrown; + #[macro_use] extern crate log; +#[cfg(feature = "lib-rust-protobuf")] extern crate protobuf; #[macro_use] extern crate quick_error; -extern crate rand; #[macro_use] extern crate getset; mod config; +#[cfg(feature = "lib-rust-protobuf")] +mod rsprotobuf; /// This module supplies the needed message types. However, it is autogenerated and thus cannot be /// documented by field. -pub mod eraftpb; +#[cfg(feature = "lib-rust-protobuf")] +pub use crate::rsprotobuf::eraftpb; mod errors; mod log_unstable; mod progress; @@ -423,21 +441,22 @@ pub mod prelude { //! //! The prelude may grow over time as additional items see ubiquitous use. - pub use eraftpb::{ + #[cfg(feature = "lib-rust-protobuf")] + pub use crate::eraftpb::{ ConfChange, ConfChangeType, ConfState, Entry, EntryType, HardState, Message, MessageType, Snapshot, SnapshotMetadata, }; - pub use config::Config; - pub use raft::Raft; + pub use crate::config::Config; + pub use crate::raft::Raft; - pub use storage::{RaftState, Storage}; + pub use crate::storage::{RaftState, Storage}; - pub use raw_node::{Peer, RawNode, Ready, SnapshotStatus}; + pub use crate::raw_node::{Peer, RawNode, Ready, SnapshotStatus}; - pub use progress::Progress; + pub use crate::progress::Progress; - pub use status::Status; + pub use crate::status::Status; - pub use read_only::{ReadOnlyOption, ReadState}; + pub use crate::read_only::{ReadOnlyOption, ReadState}; } diff --git a/src/log_unstable.rs b/src/log_unstable.rs index e4b93ca15..5304fd4f9 100644 --- a/src/log_unstable.rs +++ b/src/log_unstable.rs @@ -27,7 +27,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use eraftpb::{Entry, Snapshot}; +use crate::eraftpb::{Entry, Snapshot}; /// The unstable.entries[i] has raft log position i+unstable.offset. /// Note that unstable.offset may be less than the highest log @@ -183,9 +183,9 @@ impl Unstable { #[cfg(test)] mod test { - use eraftpb::{Entry, Snapshot, SnapshotMetadata}; + use crate::eraftpb::{Entry, Snapshot, SnapshotMetadata}; + use crate::log_unstable::Unstable; use harness::setup_for_test; - use log_unstable::Unstable; fn new_entry(index: u64, term: u64) -> Entry { let mut e = Entry::new(); diff --git a/src/progress.rs b/src/progress.rs index b2626fa48..be64372d4 100644 --- a/src/progress.rs +++ b/src/progress.rs @@ -25,8 +25,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use eraftpb::{ConfState, SnapshotMetadata}; -use errors::{Error, Result}; +use crate::eraftpb::{ConfState, SnapshotMetadata}; +use crate::errors::{Error, Result}; use hashbrown::hash_map::DefaultHashBuilder; use hashbrown::{HashMap, HashSet}; use std::cell::RefCell; @@ -958,8 +958,8 @@ impl Inflights { #[cfg(test)] mod test { + use crate::progress::Inflights; use harness::setup_for_test; - use progress::Inflights; #[test] fn test_inflight_add() { @@ -1097,7 +1097,7 @@ mod test { mod test_progress_set { use hashbrown::HashSet; - use {progress::Configuration, Progress, ProgressSet, Result}; + use crate::{progress::Configuration, Progress, ProgressSet, Result}; const CANARY: u64 = 123; diff --git a/src/raft.rs b/src/raft.rs index 3896c4111..a68696cc8 100644 --- a/src/raft.rs +++ b/src/raft.rs @@ -27,11 +27,13 @@ use std::cmp; -use eraftpb::{ +use crate::eraftpb::{ ConfChange, ConfChangeType, Entry, EntryType, HardState, Message, MessageType, Snapshot, }; use hashbrown::{HashMap, HashSet}; +#[cfg(feature = "lib-rust-protobuf")] use protobuf; +#[cfg(feature = "lib-rust-protobuf")] use protobuf::RepeatedField; use rand::{self, Rng}; @@ -685,6 +687,7 @@ impl Raft { fn append_finalize_conf_change_entry(&mut self) { let mut conf_change = ConfChange::new(); conf_change.set_change_type(ConfChangeType::FinalizeMembershipChange); + #[cfg(feature = "lib-rust-protobuf")] let data = protobuf::Message::write_to_bytes(&conf_change).unwrap(); let mut entry = Entry::new(); entry.set_entry_type(EntryType::EntryConfChange); @@ -1657,7 +1660,7 @@ impl Raft { self.bcast_heartbeat_with_ctx(Some(ctx)); } ReadOnlyOption::LeaseBased => { - let mut read_index = self.raft_log.committed; + let read_index = self.raft_log.committed; if m.get_from() == INVALID_ID || m.get_from() == self.id { // from local member let rs = ReadState { @@ -2117,6 +2120,7 @@ impl Raft { conf_change.set_change_type(ConfChangeType::BeginMembershipChange); conf_change.set_configuration(config.into()); conf_change.set_start_index(destination_index); + #[cfg(feature = "lib-rust-protobuf")] let data = protobuf::Message::write_to_bytes(&conf_change)?; let mut entry = Entry::new(); entry.set_entry_type(EntryType::EntryConfChange); diff --git a/src/raft_log.rs b/src/raft_log.rs index 4d8942c9f..b51034a7b 100644 --- a/src/raft_log.rs +++ b/src/raft_log.rs @@ -27,14 +27,14 @@ use std::cmp; -use eraftpb::{Entry, Snapshot}; +use crate::eraftpb::{Entry, Snapshot}; -use errors::{Error, Result, StorageError}; -use log_unstable::Unstable; -use storage::Storage; -use util; +use crate::errors::{Error, Result, StorageError}; +use crate::log_unstable::Unstable; +use crate::storage::Storage; +use crate::util; -pub use util::NO_LIMIT; +pub use crate::util::NO_LIMIT; /// Raft log implementation #[derive(Default)] @@ -495,12 +495,13 @@ impl RaftLog { mod test { use std::panic::{self, AssertUnwindSafe}; - use eraftpb; - use errors::{Error, StorageError}; + use crate::eraftpb; + use crate::errors::{Error, StorageError}; + use crate::raft_log::{self, RaftLog}; + use crate::storage::MemStorage; use harness::setup_for_test; + #[cfg(feature = "lib-rust-protobuf")] use protobuf; - use raft_log::{self, RaftLog}; - use storage::MemStorage; fn new_raft_log(s: MemStorage) -> RaftLog { RaftLog::new(s, String::from("")) @@ -966,6 +967,9 @@ mod test { let (offset, num) = (100u64, 100u64); let (last, half) = (offset + num, offset + num / 2); let halfe = new_entry(half, half); + + // TODO: consider refactoring because prost can't "compute_size" + #[cfg(feature = "lib-rust-protobuf")] let halfe_size = u64::from(protobuf::Message::compute_size(&halfe)); let store = MemStorage::new(); diff --git a/src/raw_node.rs b/src/raw_node.rs index ed0f10132..81d4b6ade 100644 --- a/src/raw_node.rs +++ b/src/raw_node.rs @@ -32,10 +32,11 @@ use std::mem; -use eraftpb::{ +use crate::eraftpb::{ ConfChange, ConfChangeType, ConfState, Entry, EntryType, HardState, Message, MessageType, Snapshot, }; +#[cfg(feature = "lib-rust-protobuf")] use protobuf::{self, RepeatedField}; use super::config::Config; @@ -239,6 +240,7 @@ impl RawNode { if let Some(ctx) = peer.context.take() { cc.set_context(ctx); } + #[cfg(feature = "lib-rust-protobuf")] let data = protobuf::Message::write_to_bytes(&cc).expect("unexpected marshal error"); let mut e = Entry::new(); @@ -319,6 +321,7 @@ impl RawNode { /// ProposeConfChange proposes a config change. #[cfg_attr(feature = "cargo-clippy", allow(clippy::needless_pass_by_value))] + #[cfg(feature = "lib-rust-protobuf")] pub fn propose_conf_change(&mut self, context: Vec, cc: ConfChange) -> Result<()> { let data = protobuf::Message::write_to_bytes(&cc)?; let mut m = Message::new(); @@ -531,7 +534,7 @@ impl RawNode { #[cfg(test)] mod test { use super::is_local_msg; - use eraftpb::MessageType; + use crate::eraftpb::MessageType; use harness::setup_for_test; #[test] diff --git a/src/read_only.rs b/src/read_only.rs index a51a3475a..d605f072e 100644 --- a/src/read_only.rs +++ b/src/read_only.rs @@ -27,7 +27,7 @@ use std::collections::VecDeque; -use eraftpb::Message; +use crate::eraftpb::Message; use hashbrown::{HashMap, HashSet}; diff --git a/src/rsprotobuf.rs b/src/rsprotobuf.rs new file mode 100644 index 000000000..95a8c3b3d --- /dev/null +++ b/src/rsprotobuf.rs @@ -0,0 +1 @@ +pub mod eraftpb; diff --git a/src/eraftpb.rs b/src/rsprotobuf/eraftpb.rs similarity index 95% rename from src/eraftpb.rs rename to src/rsprotobuf/eraftpb.rs index dd3008ccc..5c5a75a83 100644 --- a/src/eraftpb.rs +++ b/src/rsprotobuf/eraftpb.rs @@ -1,4 +1,4 @@ -// This file is generated by rust-protobuf 2.2.2. Do not edit +// This file is generated by rust-protobuf 2.3.0. Do not edit // @generated // https://github.com/Manishearth/rust-clippy/issues/702 @@ -158,12 +158,12 @@ impl ::protobuf::Message for Entry { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - if wire_type == ::protobuf::wire_format::WireTypeVarint {self.entry_type = is.read_enum()?;} else { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } + if wire_type == ::protobuf::wire_format::WireTypeVarint {self.entry_type = is.read_enum()?;} else {return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));} }, 2 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -227,7 +227,7 @@ impl ::protobuf::Message for Entry { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { if self.entry_type != EntryType::EntryNormal { os.write_enum(1, self.entry_type.value())?; } @@ -262,13 +262,13 @@ impl ::protobuf::Message for Entry { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: Box) -> ::std::boxed::Box { self } @@ -351,13 +351,13 @@ impl ::protobuf::Clear for Entry { } impl ::std::fmt::Debug for Entry { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for Entry { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Message(self) } } @@ -507,7 +507,7 @@ impl ::protobuf::Message for SnapshotMetadata { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { @@ -572,7 +572,7 @@ impl ::protobuf::Message for SnapshotMetadata { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { if let Some(ref v) = self.conf_state.as_ref() { os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; os.write_raw_varint32(v.get_cached_size())?; @@ -608,13 +608,13 @@ impl ::protobuf::Message for SnapshotMetadata { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: Box) -> ::std::boxed::Box { self } @@ -691,13 +691,13 @@ impl ::protobuf::Clear for SnapshotMetadata { } impl ::std::fmt::Debug for SnapshotMetadata { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for SnapshotMetadata { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Message(self) } } @@ -787,7 +787,7 @@ impl ::protobuf::Message for Snapshot { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { @@ -821,7 +821,7 @@ impl ::protobuf::Message for Snapshot { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { if !self.data.is_empty() { os.write_bytes(1, &self.data)?; } @@ -846,13 +846,13 @@ impl ::protobuf::Message for Snapshot { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: Box) -> ::std::boxed::Box { self } @@ -911,13 +911,13 @@ impl ::protobuf::Clear for Snapshot { } impl ::std::fmt::Debug for Snapshot { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for Snapshot { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Message(self) } } @@ -1182,12 +1182,12 @@ impl ::protobuf::Message for Message { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { 1 => { - if wire_type == ::protobuf::wire_format::WireTypeVarint {self.msg_type = is.read_enum()?;} else { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } + if wire_type == ::protobuf::wire_format::WireTypeVarint {self.msg_type = is.read_enum()?;} else {return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));} }, 2 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -1309,7 +1309,7 @@ impl ::protobuf::Message for Message { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { if self.msg_type != MessageType::MsgHup { os.write_enum(1, self.msg_type.value())?; } @@ -1366,13 +1366,13 @@ impl ::protobuf::Message for Message { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: Box) -> ::std::boxed::Box { self } @@ -1491,13 +1491,13 @@ impl ::protobuf::Clear for Message { } impl ::std::fmt::Debug for Message { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for Message { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Message(self) } } @@ -1569,7 +1569,7 @@ impl ::protobuf::Message for HardState { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { @@ -1620,7 +1620,7 @@ impl ::protobuf::Message for HardState { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { if self.term != 0 { os.write_uint64(1, self.term)?; } @@ -1646,13 +1646,13 @@ impl ::protobuf::Message for HardState { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: Box) -> ::std::boxed::Box { self } @@ -1717,13 +1717,13 @@ impl ::protobuf::Clear for HardState { } impl ::std::fmt::Debug for HardState { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for HardState { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Message(self) } } @@ -1799,7 +1799,7 @@ impl ::protobuf::Message for ConfState { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { @@ -1832,7 +1832,7 @@ impl ::protobuf::Message for ConfState { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { for v in &self.nodes { os.write_uint64(1, *v)?; }; @@ -1855,13 +1855,13 @@ impl ::protobuf::Message for ConfState { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: Box) -> ::std::boxed::Box { self } @@ -1920,13 +1920,13 @@ impl ::protobuf::Clear for ConfState { } impl ::std::fmt::Debug for ConfState { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for ConfState { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Message(self) } } @@ -2080,7 +2080,7 @@ impl ::protobuf::Message for ConfChange { true } - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { while !is.eof()? { let (field_number, wire_type) = is.read_tag_unpack()?; match field_number { @@ -2092,7 +2092,7 @@ impl ::protobuf::Message for ConfChange { self.id = tmp; }, 2 => { - if wire_type == ::protobuf::wire_format::WireTypeVarint {self.change_type = is.read_enum()?;} else { return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); } + if wire_type == ::protobuf::wire_format::WireTypeVarint {self.change_type = is.read_enum()?;} else {return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));} }, 3 => { if wire_type != ::protobuf::wire_format::WireTypeVarint { @@ -2150,7 +2150,7 @@ impl ::protobuf::Message for ConfChange { my_size } - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { if self.id != 0 { os.write_uint64(1, self.id)?; } @@ -2187,13 +2187,13 @@ impl ::protobuf::Message for ConfChange { &mut self.unknown_fields } - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any + fn as_any(&self) -> &dyn (::std::any::Any) { + self as &dyn (::std::any::Any) } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any + fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { + self as &mut dyn (::std::any::Any) } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { + fn into_any(self: Box) -> ::std::boxed::Box { self } @@ -2276,13 +2276,13 @@ impl ::protobuf::Clear for ConfChange { } impl ::std::fmt::Debug for ConfChange { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { ::protobuf::text_format::fmt(self, f) } } impl ::protobuf::reflect::ProtobufValue for ConfChange { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Message(self) } } @@ -2337,7 +2337,7 @@ impl ::std::default::Default for EntryType { } impl ::protobuf::reflect::ProtobufValue for EntryType { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) } } @@ -2443,7 +2443,7 @@ impl ::std::default::Default for MessageType { } impl ::protobuf::reflect::ProtobufValue for MessageType { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) } } @@ -2507,7 +2507,7 @@ impl ::std::default::Default for ConfChangeType { } impl ::protobuf::reflect::ProtobufValue for ConfChangeType { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { + fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef<'_> { ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) } } diff --git a/src/status.rs b/src/status.rs index ce9c1bd1d..93e01ccd3 100644 --- a/src/status.rs +++ b/src/status.rs @@ -25,12 +25,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use eraftpb::HardState; +use crate::eraftpb::HardState; use hashbrown::HashMap; -use progress::Progress; -use raft::{Raft, SoftState, StateRole}; -use storage::Storage; +use crate::progress::Progress; +use crate::raft::{Raft, SoftState, StateRole}; +use crate::storage::Storage; /// Represents the current status of the raft #[derive(Default)] diff --git a/src/storage.rs b/src/storage.rs index a54f7be98..3a26a0ecf 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -33,10 +33,10 @@ use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; -use eraftpb::{ConfChange, ConfState, Entry, HardState, Snapshot}; +use crate::eraftpb::{ConfChange, ConfState, Entry, HardState, Snapshot}; -use errors::{Error, Result, StorageError}; -use util; +use crate::errors::{Error, Result, StorageError}; +use crate::util; /// Holds both the hard state (commit index, vote leader, term) and the configuration state /// (Current node IDs) @@ -276,13 +276,13 @@ impl MemStorage { /// Opens up a read lock on the storage and returns a guard handle. Use this /// with functions that don't require mutation. - pub fn rl(&self) -> RwLockReadGuard { + pub fn rl(&self) -> RwLockReadGuard<'_, MemStorageCore> { self.core.read().unwrap() } /// Opens up a write lock on the storage and returns guard handle. Use this /// with functions that take a mutable reference to self. - pub fn wl(&self) -> RwLockWriteGuard { + pub fn wl(&self) -> RwLockWriteGuard<'_, MemStorageCore> { self.core.write().unwrap() } } @@ -374,14 +374,14 @@ impl Storage for MemStorage { #[cfg(test)] mod test { - extern crate harness; - use eraftpb::{ConfState, Entry, Snapshot}; + use crate::eraftpb::{ConfState, Entry, Snapshot}; + use crate::errors::{Error as RaftError, StorageError}; + use crate::storage::{MemStorage, Storage}; + use harness; use harness::setup_for_test; + #[cfg(feature = "lib-rust-protobuf")] use protobuf; - use errors::{Error as RaftError, StorageError}; - use storage::{MemStorage, Storage}; - // TODO extract these duplicated utility functions for tests fn new_entry(index: u64, term: u64) -> Entry { @@ -391,6 +391,7 @@ mod test { e } + #[cfg(feature = "lib-rust-protobuf")] fn size_of(m: &T) -> u32 { m.compute_size() } diff --git a/src/util.rs b/src/util.rs index cfddf2ea6..06bd56758 100644 --- a/src/util.rs +++ b/src/util.rs @@ -16,7 +16,8 @@ use std::u64; -use eraftpb::{ConfChange, ConfChangeType, ConfState}; +use crate::eraftpb::{ConfChange, ConfChangeType, ConfState}; +#[cfg(feature = "lib-rust-protobuf")] use protobuf::Message; /// A number to represent that there is no limit. diff --git a/tests/failpoint_cases/mod.rs b/tests/failpoint_cases/mod.rs index 4b5f4f505..00a8c5323 100644 --- a/tests/failpoint_cases/mod.rs +++ b/tests/failpoint_cases/mod.rs @@ -11,11 +11,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::test_util::*; use fail; use harness::setup_for_test; use raft::eraftpb::MessageType; use std::sync::*; -use test_util::*; lazy_static! { /// Failpoints are global structs, hence rules set in different cases diff --git a/tests/integration_cases/test_membership_changes.rs b/tests/integration_cases/test_membership_changes.rs index c96e633f1..95a24e95d 100644 --- a/tests/integration_cases/test_membership_changes.rs +++ b/tests/integration_cases/test_membership_changes.rs @@ -12,6 +12,7 @@ // limitations under the License. // // +use crate::test_util::new_message; use harness::{setup_for_test, Network}; use hashbrown::{HashMap, HashSet}; use protobuf::{self, RepeatedField}; @@ -23,7 +24,6 @@ use raft::{ Config, Configuration, Raft, Result, INVALID_ID, NO_LIMIT, }; use std::ops::{Deref, DerefMut}; -use test_util::new_message; // Test that the API itself works. // diff --git a/tests/integration_cases/test_raft.rs b/tests/integration_cases/test_raft.rs index 1d58ec740..c02c21965 100644 --- a/tests/integration_cases/test_raft.rs +++ b/tests/integration_cases/test_raft.rs @@ -29,6 +29,7 @@ use std::cmp; use std::collections::HashMap; use std::panic::{self, AssertUnwindSafe}; +use crate::test_util::*; use harness::*; use hashbrown::HashSet; use protobuf::{self, RepeatedField}; @@ -37,7 +38,6 @@ use raft::eraftpb::{ }; use raft::storage::MemStorage; use raft::*; -use test_util::*; fn new_progress( state: ProgressState, diff --git a/tests/integration_cases/test_raft_flow_control.rs b/tests/integration_cases/test_raft_flow_control.rs index 8f161734b..1bac005f9 100644 --- a/tests/integration_cases/test_raft_flow_control.rs +++ b/tests/integration_cases/test_raft_flow_control.rs @@ -25,9 +25,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::test_util::*; use harness::setup_for_test; use raft::eraftpb::*; -use test_util::*; // test_msg_app_flow_control_full ensures: // 1. msgApp can fill the sending window until full diff --git a/tests/integration_cases/test_raft_paper.rs b/tests/integration_cases/test_raft_paper.rs index 9eecda728..da0cc06fc 100644 --- a/tests/integration_cases/test_raft_paper.rs +++ b/tests/integration_cases/test_raft_paper.rs @@ -25,12 +25,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::test_util::*; use harness::*; use protobuf::RepeatedField; use raft::eraftpb::*; use raft::storage::MemStorage; use raft::*; -use test_util::*; fn commit_noop_entry(r: &mut Interface, s: &MemStorage) { assert_eq!(r.state, StateRole::Leader); diff --git a/tests/integration_cases/test_raft_snap.rs b/tests/integration_cases/test_raft_snap.rs index 97924e0b1..ab5c5329f 100644 --- a/tests/integration_cases/test_raft_snap.rs +++ b/tests/integration_cases/test_raft_snap.rs @@ -25,9 +25,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::test_util::*; use harness::setup_for_test; use raft::eraftpb::*; -use test_util::*; fn testing_snap() -> Snapshot { new_snapshot(11, 11, vec![1, 2]) diff --git a/tests/integration_cases/test_raw_node.rs b/tests/integration_cases/test_raw_node.rs index e253ccba8..66f39f2c7 100644 --- a/tests/integration_cases/test_raw_node.rs +++ b/tests/integration_cases/test_raw_node.rs @@ -25,12 +25,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::test_util::*; use harness::*; use protobuf::{self, ProtobufEnum}; use raft::eraftpb::*; use raft::storage::MemStorage; use raft::*; -use test_util::*; fn new_peer(id: u64) -> Peer { Peer { diff --git a/tests/tests.rs b/tests/tests.rs index 4fc218e8e..3664c2fae 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -16,16 +16,12 @@ #[macro_use] extern crate log; -extern crate protobuf; -extern crate raft; -extern crate rand; + #[cfg(feature = "failpoint")] #[macro_use] extern crate lazy_static; #[cfg(feature = "failpoint")] extern crate fail; -extern crate harness; -extern crate hashbrown; /// Get the count of macro's arguments. ///