Major sync <-> client interactions refactoring (#1572)

* chain notify trait

* replaced network service with io service

* fix ethcore crate warnings

* refactored network service without generic

* ethcore fix

* ethsync refactoring

* proper linking of notify

* manage network interface

* rpc crate rebinding

* full rewire

* sync internal io service

* fix deadlock

* fix warnings and removed async io

* sync imported message propagation

* fix rpc warnings

* binart warnings

* test fixes

* rpc mocks and tests

* fix util doctest

* fix message name and removed empty notifier

* pointers mess & dark mode fixed

* fixed sync doctest

* added few warnings

* fix review

* new convention match

* fix error unwraps

* doctest fix
This commit is contained in:
Nikolay Volf
2016-07-11 17:02:42 +02:00
committed by Arkadiy Paronyan
parent 2382d779ca
commit d3695d0b72
23 changed files with 469 additions and 418 deletions

View File

@@ -136,11 +136,11 @@ pub type ProtocolId = &'static str;
/// Messages used to communitate with the event loop from other threads.
#[derive(Clone)]
pub enum NetworkIoMessage<Message> where Message: Send + Sync + Clone {
pub enum NetworkIoMessage {
/// Register a new protocol handler.
AddHandler {
/// Handler shared instance.
handler: Arc<NetworkProtocolHandler<Message> + Sync>,
handler: Arc<NetworkProtocolHandler + Sync>,
/// Protocol Id.
protocol: ProtocolId,
/// Supported protocol versions.
@@ -163,8 +163,6 @@ pub enum NetworkIoMessage<Message> where Message: Send + Sync + Clone {
DisablePeer(PeerId),
/// Network has been started with the host as the given enode.
NetworkStarted(String),
/// User message
User(Message),
}
/// Local (temporary) peer session ID.
@@ -188,8 +186,8 @@ impl Encodable for CapabilityInfo {
}
/// IO access point. This is passed to all IO handlers and provides an interface to the IO subsystem.
pub struct NetworkContext<'s, Message> where Message: Send + Sync + Clone + 'static, 's {
io: &'s IoContext<NetworkIoMessage<Message>>,
pub struct NetworkContext<'s> {
io: &'s IoContext<NetworkIoMessage>,
protocol: ProtocolId,
sessions: Arc<RwLock<Slab<SharedSession>>>,
session: Option<SharedSession>,
@@ -197,12 +195,12 @@ pub struct NetworkContext<'s, Message> where Message: Send + Sync + Clone + 'sta
_reserved_peers: &'s HashSet<NodeId>,
}
impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone + 'static, {
impl<'s> NetworkContext<'s> {
/// Create a new network IO access point. Takes references to all the data that can be updated within the IO handler.
fn new(io: &'s IoContext<NetworkIoMessage<Message>>,
fn new(io: &'s IoContext<NetworkIoMessage>,
protocol: ProtocolId,
session: Option<SharedSession>, sessions: Arc<RwLock<Slab<SharedSession>>>,
reserved_peers: &'s HashSet<NodeId>) -> NetworkContext<'s, Message> {
reserved_peers: &'s HashSet<NodeId>) -> NetworkContext<'s> {
let id = session.as_ref().map(|s| s.locked().token());
NetworkContext {
io: io,
@@ -238,13 +236,8 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone
self.send(self.session_id.unwrap(), packet_id, data)
}
/// Send an IO message
pub fn message(&self, msg: Message) -> Result<(), UtilError> {
self.io.message(NetworkIoMessage::User(msg))
}
/// Get an IoChannel.
pub fn io_channel(&self) -> IoChannel<NetworkIoMessage<Message>> {
pub fn io_channel(&self) -> IoChannel<NetworkIoMessage> {
self.io.channel()
}
@@ -333,13 +326,13 @@ struct ProtocolTimer {
}
/// Root IO handler. Manages protocol handlers, IO timers and network connections.
pub struct Host<Message> where Message: Send + Sync + Clone {
pub struct Host {
pub info: RwLock<HostInfo>,
tcp_listener: Mutex<TcpListener>,
sessions: Arc<RwLock<Slab<SharedSession>>>,
discovery: Mutex<Option<Discovery>>,
nodes: RwLock<NodeTable>,
handlers: RwLock<HashMap<ProtocolId, Arc<NetworkProtocolHandler<Message>>>>,
handlers: RwLock<HashMap<ProtocolId, Arc<NetworkProtocolHandler>>>,
timers: RwLock<HashMap<TimerToken, ProtocolTimer>>,
timer_counter: RwLock<usize>,
stats: Arc<NetworkStats>,
@@ -348,9 +341,9 @@ pub struct Host<Message> where Message: Send + Sync + Clone {
stopping: AtomicBool,
}
impl<Message> Host<Message> where Message: Send + Sync + Clone {
impl Host {
/// Create a new instance
pub fn new(config: NetworkConfiguration, stats: Arc<NetworkStats>) -> Result<Host<Message>, UtilError> {
pub fn new(config: NetworkConfiguration, stats: Arc<NetworkStats>) -> Result<Host, UtilError> {
trace!(target: "host", "Creating new Host object");
let mut listen_address = match config.listen_address {
@@ -381,7 +374,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
let boot_nodes = config.boot_nodes.clone();
let reserved_nodes = config.reserved_nodes.clone();
let mut host = Host::<Message> {
let mut host = Host {
info: RwLock::new(HostInfo {
keys: keys,
config: config,
@@ -444,7 +437,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
Ok(())
}
pub fn set_non_reserved_mode(&self, mode: NonReservedPeerMode, io: &IoContext<NetworkIoMessage<Message>>) {
pub fn set_non_reserved_mode(&self, mode: NonReservedPeerMode, io: &IoContext<NetworkIoMessage>) {
let mut info = self.info.unwrapped_write();
if info.config.non_reserved_mode != mode {
@@ -495,7 +488,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
r
}
pub fn stop(&self, io: &IoContext<NetworkIoMessage<Message>>) -> Result<(), UtilError> {
pub fn stop(&self, io: &IoContext<NetworkIoMessage>) -> Result<(), UtilError> {
self.stopping.store(true, AtomicOrdering::Release);
let mut to_kill = Vec::new();
for e in self.sessions.unwrapped_write().iter_mut() {
@@ -511,7 +504,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
Ok(())
}
fn init_public_interface(&self, io: &IoContext<NetworkIoMessage<Message>>) -> Result<(), UtilError> {
fn init_public_interface(&self, io: &IoContext<NetworkIoMessage>) -> Result<(), UtilError> {
if self.info.unwrapped_read().public_endpoint.is_some() {
return Ok(());
}
@@ -567,7 +560,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
Ok(())
}
fn maintain_network(&self, io: &IoContext<NetworkIoMessage<Message>>) {
fn maintain_network(&self, io: &IoContext<NetworkIoMessage>) {
self.keep_alive(io);
self.connect_peers(io);
}
@@ -588,7 +581,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
self.sessions.unwrapped_read().count() - self.session_count()
}
fn keep_alive(&self, io: &IoContext<NetworkIoMessage<Message>>) {
fn keep_alive(&self, io: &IoContext<NetworkIoMessage>) {
let mut to_kill = Vec::new();
for e in self.sessions.unwrapped_write().iter_mut() {
let mut s = e.locked();
@@ -603,7 +596,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
}
fn connect_peers(&self, io: &IoContext<NetworkIoMessage<Message>>) {
fn connect_peers(&self, io: &IoContext<NetworkIoMessage>) {
let (ideal_peers, mut pin) = {
let info = self.info.unwrapped_read();
if info.capabilities.is_empty() {
@@ -651,7 +644,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
#[cfg_attr(feature="dev", allow(single_match))]
fn connect_peer(&self, id: &NodeId, io: &IoContext<NetworkIoMessage<Message>>) {
fn connect_peer(&self, id: &NodeId, io: &IoContext<NetworkIoMessage>) {
if self.have_session(id)
{
trace!(target: "network", "Aborted connect. Node already connected.");
@@ -688,9 +681,10 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
#[cfg_attr(feature="dev", allow(block_in_if_condition_stmt))]
fn create_connection(&self, socket: TcpStream, id: Option<&NodeId>, io: &IoContext<NetworkIoMessage<Message>>) -> Result<(), UtilError> {
fn create_connection(&self, socket: TcpStream, id: Option<&NodeId>, io: &IoContext<NetworkIoMessage>) -> Result<(), UtilError> {
let nonce = self.info.unwrapped_write().next_nonce();
let mut sessions = self.sessions.unwrapped_write();
let token = sessions.insert_with_opt(|token| {
match Session::new(io, socket, token, id, &nonce, self.stats.clone(), &self.info.unwrapped_read()) {
Ok(s) => Some(Arc::new(Mutex::new(s))),
@@ -710,7 +704,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
}
fn accept(&self, io: &IoContext<NetworkIoMessage<Message>>) {
fn accept(&self, io: &IoContext<NetworkIoMessage>) {
trace!(target: "network", "Accepting incoming connection");
loop {
let socket = match self.tcp_listener.locked().accept() {
@@ -727,8 +721,9 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
}
fn session_writable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
fn session_writable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage>) {
let session = { self.sessions.unwrapped_read().get(token).cloned() };
if let Some(session) = session {
let mut s = session.locked();
if let Err(e) = s.writable(io, &self.info.unwrapped_read()) {
@@ -740,13 +735,13 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
}
fn connection_closed(&self, token: TimerToken, io: &IoContext<NetworkIoMessage<Message>>) {
fn connection_closed(&self, token: TimerToken, io: &IoContext<NetworkIoMessage>) {
trace!(target: "network", "Connection closed: {}", token);
self.kill_connection(token, io, true);
}
#[cfg_attr(feature="dev", allow(collapsible_if))]
fn session_readable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
fn session_readable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage>) {
let mut ready_data: Vec<ProtocolId> = Vec::new();
let mut packet_data: Vec<(ProtocolId, PacketId, Vec<u8>)> = Vec::new();
let mut kill = false;
@@ -831,12 +826,12 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
}
fn connection_timeout(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
fn connection_timeout(&self, token: StreamToken, io: &IoContext<NetworkIoMessage>) {
trace!(target: "network", "Connection timeout: {}", token);
self.kill_connection(token, io, true)
}
fn kill_connection(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>, remote: bool) {
fn kill_connection(&self, token: StreamToken, io: &IoContext<NetworkIoMessage>, remote: bool) {
let mut to_disconnect: Vec<ProtocolId> = Vec::new();
let mut failure_id = None;
let mut deregister = false;
@@ -876,7 +871,7 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
}
fn update_nodes(&self, io: &IoContext<NetworkIoMessage<Message>>, node_changes: TableUpdates) {
fn update_nodes(&self, io: &IoContext<NetworkIoMessage>, node_changes: TableUpdates) {
let mut to_remove: Vec<PeerId> = Vec::new();
{
let sessions = self.sessions.unwrapped_write();
@@ -895,17 +890,24 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
}
self.nodes.unwrapped_write().update(node_changes);
}
pub fn with_context<F>(&self, protocol: ProtocolId, io: &IoContext<NetworkIoMessage>, action: F) where F: Fn(&NetworkContext) {
let reserved = { self.reserved_nodes.unwrapped_read() };
let context = NetworkContext::new(io, protocol, None, self.sessions.clone(), &reserved);
action(&context);
}
}
impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Message: Send + Sync + Clone + 'static {
impl IoHandler<NetworkIoMessage> for Host {
/// Initialize networking
fn initialize(&self, io: &IoContext<NetworkIoMessage<Message>>) {
fn initialize(&self, io: &IoContext<NetworkIoMessage>) {
io.register_timer(IDLE, MAINTENANCE_TIMEOUT).expect("Error registering Network idle timer");
io.message(NetworkIoMessage::InitPublicInterface).unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e));
self.maintain_network(io)
}
fn stream_hup(&self, io: &IoContext<NetworkIoMessage<Message>>, stream: StreamToken) {
fn stream_hup(&self, io: &IoContext<NetworkIoMessage>, stream: StreamToken) {
trace!(target: "network", "Hup: {}", stream);
match stream {
FIRST_SESSION ... LAST_SESSION => self.connection_closed(stream, io),
@@ -913,7 +915,7 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
};
}
fn stream_readable(&self, io: &IoContext<NetworkIoMessage<Message>>, stream: StreamToken) {
fn stream_readable(&self, io: &IoContext<NetworkIoMessage>, stream: StreamToken) {
if self.stopping.load(AtomicOrdering::Acquire) {
return;
}
@@ -930,7 +932,7 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
}
}
fn stream_writable(&self, io: &IoContext<NetworkIoMessage<Message>>, stream: StreamToken) {
fn stream_writable(&self, io: &IoContext<NetworkIoMessage>, stream: StreamToken) {
if self.stopping.load(AtomicOrdering::Acquire) {
return;
}
@@ -943,7 +945,7 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
}
}
fn timeout(&self, io: &IoContext<NetworkIoMessage<Message>>, token: TimerToken) {
fn timeout(&self, io: &IoContext<NetworkIoMessage>, token: TimerToken) {
if self.stopping.load(AtomicOrdering::Acquire) {
return;
}
@@ -978,7 +980,7 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
}
}
fn message(&self, io: &IoContext<NetworkIoMessage<Message>>, message: &NetworkIoMessage<Message>) {
fn message(&self, io: &IoContext<NetworkIoMessage>, message: &NetworkIoMessage) {
if self.stopping.load(AtomicOrdering::Acquire) {
return;
}
@@ -1031,19 +1033,13 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
trace!(target: "network", "Disabling peer {}", peer);
self.kill_connection(*peer, io, false);
},
NetworkIoMessage::User(ref message) => {
let reserved = self.reserved_nodes.unwrapped_read();
for (p, h) in self.handlers.unwrapped_read().iter() {
h.message(&NetworkContext::new(io, p, None, self.sessions.clone(), &reserved), &message);
}
},
NetworkIoMessage::InitPublicInterface =>
self.init_public_interface(io).unwrap_or_else(|e| warn!("Error initializing public interface: {:?}", e)),
_ => {} // ignore others.
}
}
fn register_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage<Message>>>) {
fn register_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage>>) {
match stream {
FIRST_SESSION ... LAST_SESSION => {
let session = { self.sessions.unwrapped_read().get(stream).cloned() };
@@ -1057,7 +1053,7 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
}
}
fn deregister_stream(&self, stream: StreamToken, event_loop: &mut EventLoop<IoManager<NetworkIoMessage<Message>>>) {
fn deregister_stream(&self, stream: StreamToken, event_loop: &mut EventLoop<IoManager<NetworkIoMessage>>) {
match stream {
FIRST_SESSION ... LAST_SESSION => {
let mut connections = self.sessions.unwrapped_write();
@@ -1071,7 +1067,7 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
}
}
fn update_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage<Message>>>) {
fn update_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage>>) {
match stream {
FIRST_SESSION ... LAST_SESSION => {
let connection = { self.sessions.unwrapped_read().get(stream).cloned() };
@@ -1152,6 +1148,6 @@ fn host_client_url() {
let mut config = NetworkConfiguration::new();
let key = h256_from_hex("6f7b0d801bc7b5ce7bbd930b84fd0369b3eb25d09be58d64ba811091046f3aa2");
config.use_secret = Some(key);
let host: Host<u32> = Host::new(config, Arc::new(NetworkStats::new())).unwrap();
let host: Host = Host::new(config, Arc::new(NetworkStats::new())).unwrap();
assert!(host.local_url().starts_with("enode://101b3ef5a4ea7a1c7928e24c4c75fd053c235d7b80c22ae5c03d145d0ac7396e2a4ffff9adee3133a7b05044a5cee08115fd65145e5165d646bde371010d803c@"));
}

View File

@@ -24,39 +24,30 @@
//!
//! struct MyHandler;
//!
//! #[derive(Clone)]
//! struct MyMessage {
//! data: u32
//! }
//!
//! impl NetworkProtocolHandler<MyMessage> for MyHandler {
//! fn initialize(&self, io: &NetworkContext<MyMessage>) {
//! impl NetworkProtocolHandler for MyHandler {
//! fn initialize(&self, io: &NetworkContext) {
//! io.register_timer(0, 1000);
//! }
//!
//! fn read(&self, io: &NetworkContext<MyMessage>, peer: &PeerId, packet_id: u8, data: &[u8]) {
//! fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]) {
//! println!("Received {} ({} bytes) from {}", packet_id, data.len(), peer);
//! }
//!
//! fn connected(&self, io: &NetworkContext<MyMessage>, peer: &PeerId) {
//! fn connected(&self, io: &NetworkContext, peer: &PeerId) {
//! println!("Connected {}", peer);
//! }
//!
//! fn disconnected(&self, io: &NetworkContext<MyMessage>, peer: &PeerId) {
//! fn disconnected(&self, io: &NetworkContext, peer: &PeerId) {
//! println!("Disconnected {}", peer);
//! }
//!
//! fn timeout(&self, io: &NetworkContext<MyMessage>, timer: TimerToken) {
//! fn timeout(&self, io: &NetworkContext, timer: TimerToken) {
//! println!("Timeout {}", timer);
//! }
//!
//! fn message(&self, io: &NetworkContext<MyMessage>, message: &MyMessage) {
//! println!("Message {}", message.data);
//! }
//! }
//!
//! fn main () {
//! let mut service = NetworkService::<MyMessage>::new(NetworkConfiguration::new_local()).expect("Error creating network service");
//! let mut service = NetworkService::new(NetworkConfiguration::new_local()).expect("Error creating network service");
//! service.register_protocol(Arc::new(MyHandler), "myproto", &[1u8]);
//! service.start().expect("Error starting service");
//!
@@ -84,7 +75,6 @@ pub use network::host::PacketId;
pub use network::host::NetworkContext;
pub use network::service::NetworkService;
pub use network::host::NetworkIoMessage;
pub use network::host::NetworkIoMessage::User as UserMessage;
pub use network::error::NetworkError;
pub use network::host::NetworkConfiguration;
pub use network::stats::NetworkStats;
@@ -97,19 +87,17 @@ const PROTOCOL_VERSION: u32 = 4;
/// Network IO protocol handler. This needs to be implemented for each new subprotocol.
/// All the handler function are called from within IO event loop.
/// `Message` is the type for message data.
pub trait NetworkProtocolHandler<Message>: Sync + Send where Message: Send + Sync + Clone {
pub trait NetworkProtocolHandler: Sync + Send {
/// Initialize the handler
fn initialize(&self, _io: &NetworkContext<Message>) {}
fn initialize(&self, _io: &NetworkContext) {}
/// Called when new network packet received.
fn read(&self, io: &NetworkContext<Message>, peer: &PeerId, packet_id: u8, data: &[u8]);
fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]);
/// Called when new peer is connected. Only called when peer supports the same protocol.
fn connected(&self, io: &NetworkContext<Message>, peer: &PeerId);
fn connected(&self, io: &NetworkContext, peer: &PeerId);
/// Called when a previously connected peer disconnects.
fn disconnected(&self, io: &NetworkContext<Message>, peer: &PeerId);
fn disconnected(&self, io: &NetworkContext, peer: &PeerId);
/// Timer function called after a timeout created with `NetworkContext::timeout`.
fn timeout(&self, _io: &NetworkContext<Message>, _timer: TimerToken) {}
/// Called when a broadcasted message is received. The message can only be sent from a different IO handler.
fn message(&self, _io: &NetworkContext<Message>, _message: &Message) {}
fn timeout(&self, _io: &NetworkContext, _timer: TimerToken) {}
}
/// Non-reserved peer modes.
@@ -130,4 +118,4 @@ impl NonReservedPeerMode {
_ => None,
}
}
}
}

View File

@@ -20,30 +20,30 @@ use panics::*;
use misc::RwLockable;
use network::{NetworkProtocolHandler, NetworkConfiguration};
use network::error::NetworkError;
use network::host::{Host, NetworkIoMessage, ProtocolId};
use network::host::{Host, NetworkContext, NetworkIoMessage, ProtocolId};
use network::stats::NetworkStats;
use io::*;
/// IO Service with networking
/// `Message` defines a notification data type.
pub struct NetworkService<Message> where Message: Send + Sync + Clone + 'static {
io_service: IoService<NetworkIoMessage<Message>>,
pub struct NetworkService {
io_service: IoService<NetworkIoMessage>,
host_info: String,
host: RwLock<Option<Arc<Host<Message>>>>,
host: RwLock<Option<Arc<Host>>>,
stats: Arc<NetworkStats>,
panic_handler: Arc<PanicHandler>,
config: NetworkConfiguration,
}
impl<Message> NetworkService<Message> where Message: Send + Sync + Clone + 'static {
impl NetworkService {
/// Starts IO event loop
pub fn new(config: NetworkConfiguration) -> Result<NetworkService<Message>, UtilError> {
pub fn new(config: NetworkConfiguration) -> Result<NetworkService, UtilError> {
let panic_handler = PanicHandler::new_in_arc();
let io_service = try!(IoService::<NetworkIoMessage<Message>>::start());
let io_service = try!(IoService::<NetworkIoMessage>::start());
panic_handler.forward_from(&io_service);
let stats = Arc::new(NetworkStats::new());
let host_info = Host::<Message>::client_version();
let host_info = Host::client_version();
Ok(NetworkService {
io_service: io_service,
host_info: host_info,
@@ -55,7 +55,7 @@ impl<Message> NetworkService<Message> where Message: Send + Sync + Clone + 'stat
}
/// Regiter a new protocol handler with the event loop.
pub fn register_protocol(&self, handler: Arc<NetworkProtocolHandler<Message>+Send + Sync>, protocol: ProtocolId, versions: &[u8]) -> Result<(), NetworkError> {
pub fn register_protocol(&self, handler: Arc<NetworkProtocolHandler + Send + Sync>, protocol: ProtocolId, versions: &[u8]) -> Result<(), NetworkError> {
try!(self.io_service.send_message(NetworkIoMessage::AddHandler {
handler: handler,
protocol: protocol,
@@ -70,7 +70,7 @@ impl<Message> NetworkService<Message> where Message: Send + Sync + Clone + 'stat
}
/// Returns underlying io service.
pub fn io(&self) -> &IoService<NetworkIoMessage<Message>> {
pub fn io(&self) -> &IoService<NetworkIoMessage> {
&self.io_service
}
@@ -146,9 +146,18 @@ impl<Message> NetworkService<Message> where Message: Send + Sync + Clone + 'stat
host.set_non_reserved_mode(mode, &io_ctxt);
}
}
/// Executes action in the network context
pub fn with_context<F>(&self, protocol: ProtocolId, action: F) where F: Fn(&NetworkContext) {
let io = IoContext::new(self.io_service.channel(), 0);
let host = self.host.unwrapped_read();
if let Some(ref host) = host.as_ref() {
host.with_context(protocol, &io, action);
};
}
}
impl<Message> MayPanic for NetworkService<Message> where Message: Send + Sync + Clone + 'static {
impl MayPanic for NetworkService {
fn on_panic<F>(&self, closure: F) where F: OnPanicListener {
self.panic_handler.on_panic(closure);
}

View File

@@ -30,22 +30,17 @@ pub struct TestProtocol {
pub got_disconnect: AtomicBool,
}
#[derive(Clone)]
pub struct TestProtocolMessage {
payload: u32,
}
impl TestProtocol {
pub fn new(drop_session: bool) -> Self {
TestProtocol {
packet: Mutex::new(Vec::new()),
got_timeout: AtomicBool::new(false),
got_disconnect: AtomicBool::new(false),
TestProtocol {
packet: Mutex::new(Vec::new()),
got_timeout: AtomicBool::new(false),
got_disconnect: AtomicBool::new(false),
drop_session: drop_session,
}
}
/// Creates and register protocol with the network service
pub fn register(service: &mut NetworkService<TestProtocolMessage>, drop_session: bool) -> Arc<TestProtocol> {
pub fn register(service: &mut NetworkService, drop_session: bool) -> Arc<TestProtocol> {
let handler = Arc::new(TestProtocol::new(drop_session));
service.register_protocol(handler.clone(), "test", &[42u8, 43u8]).expect("Error registering test protocol handler");
handler
@@ -64,17 +59,17 @@ impl TestProtocol {
}
}
impl NetworkProtocolHandler<TestProtocolMessage> for TestProtocol {
fn initialize(&self, io: &NetworkContext<TestProtocolMessage>) {
impl NetworkProtocolHandler for TestProtocol {
fn initialize(&self, io: &NetworkContext) {
io.register_timer(0, 10).unwrap();
}
fn read(&self, _io: &NetworkContext<TestProtocolMessage>, _peer: &PeerId, packet_id: u8, data: &[u8]) {
fn read(&self, _io: &NetworkContext, _peer: &PeerId, packet_id: u8, data: &[u8]) {
assert_eq!(packet_id, 33);
self.packet.locked().extend(data);
}
fn connected(&self, io: &NetworkContext<TestProtocolMessage>, peer: &PeerId) {
fn connected(&self, io: &NetworkContext, peer: &PeerId) {
assert!(io.peer_info(*peer).contains("Parity"));
if self.drop_session {
io.disconnect_peer(*peer)
@@ -83,13 +78,12 @@ impl NetworkProtocolHandler<TestProtocolMessage> for TestProtocol {
}
}
fn disconnected(&self, _io: &NetworkContext<TestProtocolMessage>, _peer: &PeerId) {
fn disconnected(&self, _io: &NetworkContext, _peer: &PeerId) {
self.got_disconnect.store(true, AtomicOrdering::Relaxed);
}
/// Timer function called after a timeout created with `NetworkContext::timeout`.
fn timeout(&self, io: &NetworkContext<TestProtocolMessage>, timer: TimerToken) {
io.message(TestProtocolMessage { payload: 22 }).unwrap();
fn timeout(&self, _io: &NetworkContext, timer: TimerToken) {
assert_eq!(timer, 0);
self.got_timeout.store(true, AtomicOrdering::Relaxed);
}
@@ -98,7 +92,7 @@ impl NetworkProtocolHandler<TestProtocolMessage> for TestProtocol {
#[test]
fn net_service() {
let service = NetworkService::<TestProtocolMessage>::new(NetworkConfiguration::new_local()).expect("Error creating network service");
let service = NetworkService::new(NetworkConfiguration::new_local()).expect("Error creating network service");
service.start().unwrap();
service.register_protocol(Arc::new(TestProtocol::new(false)), "myproto", &[1u8]).unwrap();
}
@@ -110,13 +104,13 @@ fn net_connect() {
let mut config1 = NetworkConfiguration::new_local();
config1.use_secret = Some(key1.secret().clone());
config1.boot_nodes = vec![ ];
let mut service1 = NetworkService::<TestProtocolMessage>::new(config1).unwrap();
let mut service1 = NetworkService::new(config1).unwrap();
service1.start().unwrap();
let handler1 = TestProtocol::register(&mut service1, false);
let mut config2 = NetworkConfiguration::new_local();
info!("net_connect: local URL: {}", service1.local_url().unwrap());
config2.boot_nodes = vec![ service1.local_url().unwrap() ];
let mut service2 = NetworkService::<TestProtocolMessage>::new(config2).unwrap();
let mut service2 = NetworkService::new(config2).unwrap();
service2.start().unwrap();
let handler2 = TestProtocol::register(&mut service2, false);
while !handler1.got_packet() && !handler2.got_packet() && (service1.stats().sessions() == 0 || service2.stats().sessions() == 0) {
@@ -129,7 +123,7 @@ fn net_connect() {
#[test]
fn net_start_stop() {
let config = NetworkConfiguration::new_local();
let service = NetworkService::<TestProtocolMessage>::new(config).unwrap();
let service = NetworkService::new(config).unwrap();
service.start().unwrap();
service.stop().unwrap();
service.start().unwrap();
@@ -141,12 +135,12 @@ fn net_disconnect() {
let mut config1 = NetworkConfiguration::new_local();
config1.use_secret = Some(key1.secret().clone());
config1.boot_nodes = vec![ ];
let mut service1 = NetworkService::<TestProtocolMessage>::new(config1).unwrap();
let mut service1 = NetworkService::new(config1).unwrap();
service1.start().unwrap();
let handler1 = TestProtocol::register(&mut service1, false);
let mut config2 = NetworkConfiguration::new_local();
config2.boot_nodes = vec![ service1.local_url().unwrap() ];
let mut service2 = NetworkService::<TestProtocolMessage>::new(config2).unwrap();
let mut service2 = NetworkService::new(config2).unwrap();
service2.start().unwrap();
let handler2 = TestProtocol::register(&mut service2, true);
while !(handler1.got_disconnect() && handler2.got_disconnect()) {
@@ -159,7 +153,7 @@ fn net_disconnect() {
#[test]
fn net_timeout() {
let config = NetworkConfiguration::new_local();
let mut service = NetworkService::<TestProtocolMessage>::new(config).unwrap();
let mut service = NetworkService::new(config).unwrap();
service.start().unwrap();
let handler = TestProtocol::register(&mut service, false);
while !handler.got_timeout() {