Skip to content

Commit d17197f

Browse files
committed
Rewrite server example to modern async-std
1 parent ef40d88 commit d17197f

File tree

1 file changed

+54
-46
lines changed

1 file changed

+54
-46
lines changed

Diff for: examples/a-chat/server.rs

+54-46
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,16 @@ use std::{
33
sync::Arc,
44
};
55

6-
use futures::{channel::mpsc, select, FutureExt, SinkExt};
7-
86
use async_std::{
97
io::BufReader,
108
net::{TcpListener, TcpStream, ToSocketAddrs},
119
prelude::*,
1210
task,
11+
sync::{channel, Sender, Receiver},
12+
stream,
1313
};
1414

1515
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
16-
type Sender<T> = mpsc::UnboundedSender<T>;
17-
type Receiver<T> = mpsc::UnboundedReceiver<T>;
1816

1917
#[derive(Debug)]
2018
enum Void {}
@@ -26,7 +24,7 @@ pub(crate) fn main() -> Result<()> {
2624
async fn accept_loop(addr: impl ToSocketAddrs) -> Result<()> {
2725
let listener = TcpListener::bind(addr).await?;
2826

29-
let (broker_sender, broker_receiver) = mpsc::unbounded();
27+
let (broker_sender, broker_receiver) = channel(10);
3028
let broker = task::spawn(broker_loop(broker_receiver));
3129
let mut incoming = listener.incoming();
3230
while let Some(stream) = incoming.next().await {
@@ -39,7 +37,7 @@ async fn accept_loop(addr: impl ToSocketAddrs) -> Result<()> {
3937
Ok(())
4038
}
4139

42-
async fn connection_loop(mut broker: Sender<Event>, stream: TcpStream) -> Result<()> {
40+
async fn connection_loop(broker: Sender<Event>, stream: TcpStream) -> Result<()> {
4341
let stream = Arc::new(stream);
4442
let reader = BufReader::new(&*stream);
4543
let mut lines = reader.lines();
@@ -48,15 +46,14 @@ async fn connection_loop(mut broker: Sender<Event>, stream: TcpStream) -> Result
4846
None => return Err("peer disconnected immediately".into()),
4947
Some(line) => line?,
5048
};
51-
let (_shutdown_sender, shutdown_receiver) = mpsc::unbounded::<Void>();
49+
let (_shutdown_sender, shutdown_receiver) = channel::<Void>(0);
5250
broker
5351
.send(Event::NewPeer {
5452
name: name.clone(),
5553
stream: Arc::clone(&stream),
5654
shutdown: shutdown_receiver,
5755
})
58-
.await
59-
.unwrap();
56+
.await;
6057

6158
while let Some(line) = lines.next().await {
6259
let line = line?;
@@ -76,28 +73,36 @@ async fn connection_loop(mut broker: Sender<Event>, stream: TcpStream) -> Result
7673
to: dest,
7774
msg,
7875
})
79-
.await
80-
.unwrap();
76+
.await;
8177
}
8278

8379
Ok(())
8480
}
8581

82+
#[derive(Debug)]
83+
enum ConnectionWriterEvent {
84+
Message(String),
85+
Shutdown
86+
}
87+
8688
async fn connection_writer_loop(
8789
messages: &mut Receiver<String>,
8890
stream: Arc<TcpStream>,
89-
mut shutdown: Receiver<Void>,
91+
shutdown: Receiver<Void>,
9092
) -> Result<()> {
9193
let mut stream = &*stream;
92-
loop {
93-
select! {
94-
msg = messages.next().fuse() => match msg {
95-
Some(msg) => stream.write_all(msg.as_bytes()).await?,
96-
None => break,
97-
},
98-
void = shutdown.next().fuse() => match void {
99-
Some(void) => match void {},
100-
None => break,
94+
let messages = messages.map(ConnectionWriterEvent::Message);
95+
let shutdown = shutdown.map(|_| ConnectionWriterEvent::Shutdown).chain(stream::once(ConnectionWriterEvent::Shutdown));
96+
97+
let mut events = shutdown.merge(messages);
98+
99+
while let Some(event) = events.next().await {
100+
match event {
101+
ConnectionWriterEvent::Message(msg) => {
102+
stream.write_all(msg.as_bytes()).await?;
103+
}
104+
ConnectionWriterEvent::Shutdown => {
105+
break
101106
}
102107
}
103108
}
@@ -118,58 +123,61 @@ enum Event {
118123
},
119124
}
120125

121-
async fn broker_loop(mut events: Receiver<Event>) {
122-
let (disconnect_sender, mut disconnect_receiver) =
123-
mpsc::unbounded::<(String, Receiver<String>)>();
126+
#[derive(Debug)]
127+
enum BrokerEvent {
128+
ClientEvent(Event),
129+
Disconnection((String, Receiver<String>)),
130+
Shutdown,
131+
}
132+
133+
async fn broker_loop(events: Receiver<Event>) {
134+
let (disconnect_sender, disconnect_receiver) = channel(10);
135+
124136
let mut peers: HashMap<String, Sender<String>> = HashMap::new();
137+
let disconnect_receiver = disconnect_receiver.map(BrokerEvent::Disconnection);
138+
let events = events.map(BrokerEvent::ClientEvent).chain(stream::once(BrokerEvent::Shutdown));
125139

126-
loop {
127-
let event = select! {
128-
event = events.next().fuse() => match event {
129-
None => break,
130-
Some(event) => event,
131-
},
132-
disconnect = disconnect_receiver.next().fuse() => {
133-
let (name, _pending_messages) = disconnect.unwrap();
134-
assert!(peers.remove(&name).is_some());
135-
continue;
136-
},
137-
};
140+
let mut stream = disconnect_receiver.merge(events);
141+
142+
while let Some(event) = stream.next().await {
138143
match event {
139-
Event::Message { from, to, msg } => {
144+
BrokerEvent::ClientEvent(Event::Message { from, to, msg }) => {
140145
for addr in to {
141146
if let Some(peer) = peers.get_mut(&addr) {
142147
let msg = format!("from {}: {}\n", from, msg);
143-
peer.send(msg).await.unwrap();
148+
peer.send(msg).await;
144149
}
145150
}
146151
}
147-
Event::NewPeer {
152+
BrokerEvent::ClientEvent(Event::NewPeer {
148153
name,
149154
stream,
150155
shutdown,
151-
} => match peers.entry(name.clone()) {
156+
}) => match peers.entry(name.clone()) {
152157
Entry::Occupied(..) => (),
153158
Entry::Vacant(entry) => {
154-
let (client_sender, mut client_receiver) = mpsc::unbounded();
159+
let (client_sender, mut client_receiver) = channel(10);
155160
entry.insert(client_sender);
156-
let mut disconnect_sender = disconnect_sender.clone();
161+
let disconnect_sender = disconnect_sender.clone();
157162
spawn_and_log_error(async move {
158163
let res =
159164
connection_writer_loop(&mut client_receiver, stream, shutdown).await;
160165
disconnect_sender
161166
.send((name, client_receiver))
162-
.await
163-
.unwrap();
167+
.await;
164168
res
165169
});
166170
}
167-
},
171+
}
172+
BrokerEvent::Disconnection((name, _pending_messages)) => {
173+
assert!(peers.remove(&name).is_some());
174+
}
175+
BrokerEvent::Shutdown => break,
168176
}
169177
}
170178
drop(peers);
171179
drop(disconnect_sender);
172-
while let Some((_name, _pending_messages)) = disconnect_receiver.next().await {}
180+
while let Some(BrokerEvent::Disconnection((_name, _pending_messages))) = stream.next().await {}
173181
}
174182

175183
fn spawn_and_log_error<F>(fut: F) -> task::JoinHandle<()>

0 commit comments

Comments
 (0)