1
0
Fork 0
mirror of https://codeberg.org/demostf/sync.git synced 2026-06-03 16:44:07 +02:00

switch to zero-copy deserialization for SyncCommand

This commit is contained in:
Robin Appelman 2019-10-27 18:18:19 +01:00
commit 744fe16df5
3 changed files with 89 additions and 109 deletions

View file

@ -68,11 +68,19 @@ mod mock {
} }
} }
pub fn received(&self) -> Vec<SyncCommand> { pub fn received_count(&self) -> usize {
RefCell::borrow(&self.received) RefCell::borrow(&self.received).len()
}
pub fn assert_received(&self, expected: Vec<SyncCommand>) {
let map = RefCell::borrow(&self.received);
let received: Vec<_> = map
.iter() .iter()
.map(|msg| serde_json::from_str::<SyncCommand>(msg).expect("invalid message")) .map(|msg| serde_json::from_str::<SyncCommand>(msg).expect("invalid message"))
.collect() .collect();
assert_eq!(expected, received);
} }
pub fn clear(&self) { pub fn clear(&self) {

View file

@ -52,86 +52,76 @@ fn integration_tests() {
send( send(
&mut owner, &mut owner,
SyncCommand::Create { SyncCommand::Create {
session: "foo".to_string(), session: "foo",
token: "bar".to_string(), token: "bar",
}, },
); );
send( send(
&mut owner, &mut owner,
SyncCommand::Tick { SyncCommand::Tick {
session: "foo".to_string(), session: "foo",
tick: 99, tick: 99,
}, },
); );
send( send(&mut client, SyncCommand::Join { session: "foo" });
assert_receive(
&mut client, &mut client,
SyncCommand::Join { SyncCommand::Tick {
session: "foo".to_string(), session: "foo",
tick: 99,
}, },
); );
assert_receive(
assert_eq!( &mut client,
Some(SyncCommand::Tick { SyncCommand::Play {
session: "foo".to_string(), session: "foo",
tick: 99, play: false,
}), },
receive(&mut client)
);
assert_eq!(
Some(SyncCommand::Play {
session: "foo".to_string(),
play: false
}),
receive(&mut client)
); );
send( send(
&mut owner, &mut owner,
SyncCommand::Play { SyncCommand::Play {
session: "foo".to_string(), session: "foo",
play: true, play: true,
}, },
); );
assert_eq!( assert_receive(
Some(SyncCommand::Play { &mut client,
session: "foo".to_string(), SyncCommand::Play {
play: true session: "foo",
}), play: true,
receive(&mut client) },
); );
// should be ignored // should be ignored
send( send(
&mut client, &mut client,
SyncCommand::Tick { SyncCommand::Tick {
session: "foo".to_string(), session: "foo",
tick: 5, tick: 5,
}, },
); );
let mut client2 = test.get_client(); let mut client2 = test.get_client();
send( send(&mut client2, SyncCommand::Join { session: "foo" });
assert_receive(
&mut client2, &mut client2,
SyncCommand::Join { SyncCommand::Tick {
session: "foo".to_string(), session: "foo",
tick: 99,
}, },
); );
assert_receive(
assert_eq!( &mut client2,
Some(SyncCommand::Tick { SyncCommand::Play {
session: "foo".to_string(), session: "foo",
tick: 99, play: true,
}), },
receive(&mut client2)
);
assert_eq!(
Some(SyncCommand::Play {
session: "foo".to_string(),
play: true
}),
receive(&mut client2)
); );
} }
@ -142,10 +132,8 @@ fn send<T: std::io::Write>(client: &mut Client<T>, command: SyncCommand) {
sleep(DELAY); sleep(DELAY);
} }
fn receive<T: std::io::Read>(client: &mut Client<T>) -> Option<SyncCommand> { fn assert_receive<T: std::io::Read>(client: &mut Client<T>, expected: SyncCommand) {
client let message = client.receive().unwrap().unwrap();
.receive() let text = message.as_text().unwrap();
.unwrap() assert_eq!(expected, serde_json::from_str(text).unwrap());
.and_then(|message| message.as_text().map(|s| s.to_string()))
.map(|text| serde_json::from_str(&text).unwrap())
} }

View file

@ -14,11 +14,11 @@ use std::time::{Duration, Instant};
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] #[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(tag = "type")] #[serde(tag = "type")]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum SyncCommand { pub enum SyncCommand<'a> {
Create { session: String, token: String }, Create { session: &'a str, token: &'a str },
Join { session: String }, Join { session: &'a str },
Tick { session: String, tick: u64 }, Tick { session: &'a str, tick: u64 },
Play { session: String, play: bool }, Play { session: &'a str, play: bool },
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
@ -71,19 +71,19 @@ fn handle_command(
SyncCommand::Create { session, token } => { SyncCommand::Create { session, token } => {
sessions sessions
.borrow_mut() .borrow_mut()
.entry(session.clone()) .entry(session.to_string())
.and_modify(|session| { .and_modify(|session| {
if token == &session.owner_token { if token == &session.owner_token {
session.owner = sender.token(); session.owner = sender.token();
session.owner_left = None; session.owner_left = None;
} }
}) })
.or_insert_with(|| Session::new(sender.token(), token.clone())); .or_insert_with(|| Session::new(sender.token(), token.to_string()));
gc_sessions(sessions); gc_sessions(sessions);
} }
SyncCommand::Join { SyncCommand::Join {
session: session_name, session: session_name,
} => match sessions.borrow_mut().get_mut(session_name) { } => match sessions.borrow_mut().get_mut(*session_name) {
Some(session) => { Some(session) => {
session.join(sender); session.join(sender);
session.send_command(&SyncCommand::Tick { session.send_command(&SyncCommand::Tick {
@ -236,8 +236,8 @@ mod tests {
let input = "{\"type\": \"create\", \"session\": \"foo\", \"token\": \"bar\"}"; let input = "{\"type\": \"create\", \"session\": \"foo\", \"token\": \"bar\"}";
assert_eq!( assert_eq!(
SyncCommand::Create { SyncCommand::Create {
session: "foo".to_string(), session: "foo",
token: "bar".to_string(), token: "bar",
}, },
serde_json::from_str(input).unwrap() serde_json::from_str(input).unwrap()
); );
@ -249,7 +249,7 @@ mod tests {
let sender = Client::mock(1); let sender = Client::mock(1);
let command = SyncCommand::Create { let command = SyncCommand::Create {
session: "test".into(), session: "test".into(),
token: "bar".to_string(), token: "bar",
}; };
handle_command(command, &sender, &sessions); handle_command(command, &sender, &sessions);
@ -283,7 +283,7 @@ mod tests {
}); });
let sender = Client::mock(1); let sender = Client::mock(1);
let command = SyncCommand::Play { let command = SyncCommand::Play {
session: "test".into(), session: "test",
play: true, play: true,
}; };
@ -318,7 +318,7 @@ mod tests {
}); });
let sender = Client::mock(2); let sender = Client::mock(2);
let command = SyncCommand::Play { let command = SyncCommand::Play {
session: "test".into(), session: "test",
play: true, play: true,
}; };
@ -353,7 +353,7 @@ mod tests {
}); });
let sender = Client::mock(1); let sender = Client::mock(1);
let command = SyncCommand::Tick { let command = SyncCommand::Tick {
session: "test".into(), session: "test",
tick: 99, tick: 99,
}; };
@ -388,7 +388,7 @@ mod tests {
}); });
let sender = Client::mock(2); let sender = Client::mock(2);
let command = SyncCommand::Tick { let command = SyncCommand::Tick {
session: "test".into(), session: "test",
tick: 99, tick: 99,
}; };
@ -422,9 +422,7 @@ mod tests {
} }
}); });
let sender = Client::mock(2); let sender = Client::mock(2);
let command = SyncCommand::Join { let command = SyncCommand::Join { session: "test" };
session: "test".into(),
};
handle_command(command, &sender, &sessions); handle_command(command, &sender, &sessions);
@ -443,19 +441,16 @@ mod tests {
); );
if let Client::Mock(mock) = sender { if let Client::Mock(mock) = sender {
assert_eq!( mock.assert_received(vec![
vec![ SyncCommand::Tick {
SyncCommand::Tick { session: "test",
session: "test".into(), tick: 99,
tick: 99, },
}, SyncCommand::Play {
SyncCommand::Play { session: "test",
session: "test".into(), play: true,
play: true, },
} ]);
],
mock.received()
);
}; };
} }
@ -472,9 +467,7 @@ mod tests {
} }
}); });
let sender = Client::mock(2); let sender = Client::mock(2);
let command = SyncCommand::Join { let command = SyncCommand::Join { session: "test2" };
session: "test2".into(),
};
handle_command(command, &sender, &sessions); handle_command(command, &sender, &sessions);
@ -516,15 +509,11 @@ mod tests {
let owner = Client::mock(1); let owner = Client::mock(1);
let sender1 = Client::mock(2); let sender1 = Client::mock(2);
let sender2 = Client::mock(3); let sender2 = Client::mock(3);
let command = SyncCommand::Join { let command = SyncCommand::Join { session: "test" };
session: "test".into(),
};
handle_command(command, &sender1, &sessions); handle_command(command, &sender1, &sessions);
let command = SyncCommand::Join { let command = SyncCommand::Join { session: "test2" };
session: "test2".into(),
};
handle_command(command, &sender2, &sessions); handle_command(command, &sender2, &sessions);
if let Client::Mock(mock) = &sender1 { if let Client::Mock(mock) = &sender1 {
@ -535,23 +524,20 @@ mod tests {
} }
let command = SyncCommand::Tick { let command = SyncCommand::Tick {
session: "test".into(), session: "test",
tick: 999, tick: 999,
}; };
handle_command(command, &owner, &sessions); handle_command(command, &owner, &sessions);
if let Client::Mock(mock) = sender1 { if let Client::Mock(mock) = sender1 {
assert_eq!( mock.assert_received(vec![SyncCommand::Tick {
vec![SyncCommand::Tick { session: "test",
session: "test".into(), tick: 999,
tick: 999, }]);
}],
mock.received()
);
}; };
if let Client::Mock(mock) = sender2 { if let Client::Mock(mock) = sender2 {
assert_eq!(0, mock.received().len()); assert_eq!(0, mock.received_count());
}; };
} }
@ -569,9 +555,7 @@ mod tests {
}); });
let sender1 = Client::mock(2); let sender1 = Client::mock(2);
let sender2 = Client::mock(3); let sender2 = Client::mock(3);
let command = SyncCommand::Join { let command = SyncCommand::Join { session: "test" };
session: "test".into(),
};
handle_command(command.clone(), &sender1, &sessions); handle_command(command.clone(), &sender1, &sessions);
handle_command(command.clone(), &sender2, &sessions); handle_command(command.clone(), &sender2, &sessions);
@ -584,17 +568,17 @@ mod tests {
} }
let command = SyncCommand::Tick { let command = SyncCommand::Tick {
session: "test".into(), session: "test",
tick: 999, tick: 999,
}; };
handle_command(command, &sender1, &sessions); handle_command(command, &sender1, &sessions);
if let Client::Mock(mock) = sender1 { if let Client::Mock(mock) = sender1 {
assert_eq!(0, mock.received().len()); assert_eq!(0, mock.received_count());
}; };
if let Client::Mock(mock) = sender2 { if let Client::Mock(mock) = sender2 {
assert_eq!(0, mock.received().len()); assert_eq!(0, mock.received_count());
}; };
} }
} }