Skip to content

Commit

Permalink
intentevent
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgb committed Sep 7, 2024
1 parent 3b98467 commit b665144
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 47 deletions.
20 changes: 3 additions & 17 deletions aper-websocket-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::typed::TypedWebsocketConnection;
use anyhow::Result;
use aper::{
connection::{ClientConnection, MessageToClient, MessageToServer},
Aper, AperClient, IntentEvent, Store,
Aper, AperClient, Store,
};
use core::fmt::Debug;
use std::{
Expand Down Expand Up @@ -43,14 +43,7 @@ where
pub fn apply(&self, intent: S::Intent) {
let mut conn = self.conn.lock().unwrap();

let client = conn.client_id;
let intent = IntentEvent {
client,
timestamp: chrono::Utc::now(),
intent,
};

if let Err(err) = conn.apply(&intent) {
if let Err(err) = conn.apply(intent) {
tracing::error!("Error applying intent: {:?}", err);
}
}
Expand Down Expand Up @@ -117,13 +110,6 @@ where
pub fn apply(&self, intent: S::Intent) -> Result<(), S::Error> {
let mut conn = self.conn.lock().unwrap();

let client = conn.client_id;
let intent = IntentEvent {
client,
timestamp: chrono::Utc::now(),
intent,
};

conn.apply(&intent)
conn.apply(intent)
}
}
2 changes: 1 addition & 1 deletion aper/src/aper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl<A: Aper> AperClient<A> {
{
let mut sm = A::attach(self.store.handle());

if let Err(e) = sm.apply(intent) {
if let Err(e) = sm.apply(&intent) {
// reverse changes.
self.store.pop_overlay();
return Err(e);
Expand Down
15 changes: 10 additions & 5 deletions aper/src/connection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Aper, AperClient, AperServer, IntentEvent, Store};
use crate::{Aper, AperClient, AperServer, Store};
use chrono::{DateTime, Utc};
use dashmap::DashMap;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -41,7 +41,7 @@ pub struct MessageToClient {
pub struct ClientConnection<A: Aper> {
client: AperClient<A>,
message_callback: Box<dyn Fn(MessageToServer)>,
pub client_id: Option<u32>,
client_id: Option<u32>,
}

impl<A: Aper> ClientConnection<A> {
Expand All @@ -62,6 +62,10 @@ impl<A: Aper> ClientConnection<A> {
}
}

pub fn client_id(&self) -> Option<u32> {
self.client_id
}

pub fn state(&self) -> A {
self.client.state()
}
Expand All @@ -71,9 +75,10 @@ impl<A: Aper> ClientConnection<A> {
}

/// Send an intent to the server, and apply it speculatively to the local state.
pub fn apply(&mut self, intent: &IntentEvent<A::Intent>) -> Result<(), A::Error> {
let version = self.client.apply(intent)?;
let intent = bincode::serialize(intent).unwrap();
pub fn apply(&mut self, intent: A::Intent) -> Result<(), A::Error> {
let intent = crate::IntentEvent::new(self.client_id, Utc::now(), intent);
let version = self.client.apply(&intent)?;
let intent = bincode::serialize(&intent).unwrap();
(self.message_callback)(MessageToServer::Intent {
intent,
client_version: version,
Expand Down
8 changes: 8 additions & 0 deletions aper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,12 @@ impl<T> IntentEvent<T> {
intent,
}
}

pub fn simple(intent: T) -> IntentEvent<T> {
IntentEvent {
timestamp: Utc::now(),
client: None,
intent,
}
}
}
20 changes: 14 additions & 6 deletions aper/tests/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,27 @@ fn test_apply_listener() {
st.fixed_array
.listen(move || fixed_array_send.send(()).is_ok());

client.apply(&SimpleIntent::SetAtomI32(42)).unwrap();
client
.apply(&IntentEvent::simple(SimpleIntent::SetAtomI32(42)))
.unwrap();

assert!(atom_i32_recv.try_recv().is_ok());
assert!(atom_string_recv.try_recv().is_err());
assert!(fixed_array_recv.try_recv().is_err());

client
.apply(&SimpleIntent::SetAtomString("hello".to_string()))
.apply(&IntentEvent::simple(SimpleIntent::SetAtomString(
"hello".to_string(),
)))
.unwrap();

assert!(atom_i32_recv.try_recv().is_err());
assert!(atom_string_recv.try_recv().is_ok());
assert!(fixed_array_recv.try_recv().is_err());

client.apply(&SimpleIntent::SetFixedArray(0, 42)).unwrap();
client
.apply(&IntentEvent::simple(SimpleIntent::SetFixedArray(0, 42)))
.unwrap();

assert!(atom_i32_recv.try_recv().is_err());
assert!(atom_string_recv.try_recv().is_err());
Expand Down Expand Up @@ -135,8 +141,8 @@ impl Aper for LinkedFields {
type Intent = LinkedFieldIntent;
type Error = ();

fn apply(&mut self, intent: &Self::Intent) -> Result<(), Self::Error> {
match intent {
fn apply(&mut self, intent: &IntentEvent<Self::Intent>) -> Result<(), Self::Error> {
match &intent.intent {
LinkedFieldIntent::SetLhs(value) => self.lhs.set(*value),
LinkedFieldIntent::SetRhs(value) => self.rhs.set(*value),
}
Expand All @@ -163,7 +169,9 @@ fn test_mutate_listener_incidental() {
st.rhs.listen(move || rhs_send.send(()).is_ok());
st.sum.listen(move || sum_send.send(()).is_ok());

client.apply(&LinkedFieldIntent::SetLhs(1)).unwrap();
client
.apply(&IntentEvent::simple(LinkedFieldIntent::SetLhs(1)))
.unwrap();

assert_eq!(1, st.lhs.get());
assert_eq!(1, st.sum.get());
Expand Down
26 changes: 17 additions & 9 deletions aper/tests/simple-client-server.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use aper::{data_structures::atom::Atom, Aper, AperClient, AperServer, AperSync, StoreHandle};
use aper::{
data_structures::atom::Atom, Aper, AperClient, AperServer, AperSync, IntentEvent, StoreHandle,
};
use serde::{Deserialize, Serialize};

struct Counter(Atom<u64>);
Expand All @@ -25,8 +27,8 @@ impl Aper for Counter {
type Intent = CounterIntent;
type Error = ();

fn apply(&mut self, intent: &Self::Intent) -> Result<(), Self::Error> {
match intent {
fn apply(&mut self, intent: &IntentEvent<Self::Intent>) -> Result<(), Self::Error> {
match &intent.intent {
CounterIntent::IncrementBy(amount) => {
self.0.set(self.0.get() + amount);
}
Expand All @@ -44,13 +46,16 @@ fn test_local_change() {
let mut client = AperClient::<Counter>::new();
let mut server = AperServer::<Counter>::new();

let intent = CounterIntent::IncrementBy(5);
let version = client.apply(&intent).unwrap();
let version = client
.apply(&IntentEvent::simple(CounterIntent::IncrementBy(5)))
.unwrap();

assert_eq!(1, version);
assert_eq!(0, client.verified_client_version());
assert_eq!(1, client.speculative_client_version());

let intent = IntentEvent::new(None, chrono::Utc::now(), CounterIntent::IncrementBy(5));

let mutations = server.apply(&intent).unwrap();

client.mutate(&mutations, Some(version), 1);
Expand All @@ -66,7 +71,7 @@ fn test_local_change() {
fn test_remote_change() {
let mut server = AperServer::<Counter>::new();

let intent = CounterIntent::IncrementBy(5);
let intent = IntentEvent::new(None, chrono::Utc::now(), CounterIntent::IncrementBy(5));
let mutations = server.apply(&intent).unwrap();

let mut client = AperClient::<Counter>::new();
Expand All @@ -87,9 +92,12 @@ fn test_speculative_change_remains() {
let mut server = AperServer::<Counter>::new();
let mut client = AperClient::<Counter>::new();

client.apply(&CounterIntent::IncrementBy(5)).unwrap();
client
.apply(&IntentEvent::simple(CounterIntent::IncrementBy(5)))
.unwrap();

let mutations = server.apply(&CounterIntent::SetTo(10)).unwrap();
let intent = IntentEvent::new(None, chrono::Utc::now(), CounterIntent::IncrementBy(10));
let mutations = server.apply(&intent).unwrap();

client.mutate(&mutations, None, 1);

Expand All @@ -105,7 +113,7 @@ fn test_remote_changes_persist() {
let mut server = AperServer::<Counter>::new();
let mut client = AperClient::<Counter>::new();

let intent = CounterIntent::IncrementBy(5);
let intent = IntentEvent::simple(CounterIntent::IncrementBy(5));
let mutations = server.apply(&intent).unwrap();
client.mutate(&mutations, None, 1);

Expand Down
24 changes: 15 additions & 9 deletions aper/tests/tic-tac-toe.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use aper::{
data_structures::{atom::Atom, fixed_array::FixedArray},
Aper, AperSync, Store,
Aper, AperSync, IntentEvent, Store,
};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -55,10 +55,10 @@ impl Aper for TicTacToe {
type Intent = TicTacToePlay;
type Error = ();

fn apply(&mut self, intent: &Self::Intent) -> Result<(), Self::Error> {
fn apply(&mut self, intent: &IntentEvent<Self::Intent>) -> Result<(), Self::Error> {
let player = self.player.get();

match intent {
match &intent.intent {
TicTacToePlay::Play(cell) => {
self.grid.set(*cell as u32, Some(player));
self.player.set(match player {
Expand Down Expand Up @@ -89,10 +89,14 @@ fn test_tic_tac_toe() {
let map = Store::default();
let mut game = TicTacToe::attach(map.handle());

game.apply(&TicTacToePlay::Play(0)).unwrap(); // X
game.apply(&TicTacToePlay::Play(1)).unwrap(); // O
game.apply(&TicTacToePlay::Play(3)).unwrap(); // X
game.apply(&TicTacToePlay::Play(2)).unwrap(); // O
game.apply(&IntentEvent::simple(TicTacToePlay::Play(0)))
.unwrap(); // X
game.apply(&IntentEvent::simple(TicTacToePlay::Play(1)))
.unwrap(); // O
game.apply(&IntentEvent::simple(TicTacToePlay::Play(3)))
.unwrap(); // X
game.apply(&IntentEvent::simple(TicTacToePlay::Play(2)))
.unwrap(); // O

assert_eq!(game.grid.get(0), Some(TicTacToePlayer::X));
assert_eq!(game.grid.get(1), Some(TicTacToePlayer::O));
Expand All @@ -101,10 +105,12 @@ fn test_tic_tac_toe() {

assert_eq!(game.winner.get(), None);

game.apply(&TicTacToePlay::Play(6)).unwrap(); // X for the win
game.apply(&IntentEvent::simple(TicTacToePlay::Play(6)))
.unwrap(); // X for the win
assert_eq!(game.winner.get(), Some(TicTacToePlayer::X));

game.apply(&TicTacToePlay::Reset).unwrap();
game.apply(&IntentEvent::simple(TicTacToePlay::Reset))
.unwrap();

for i in 0..9 {
assert_eq!(game.grid.get(i), None);
Expand Down

0 comments on commit b665144

Please sign in to comment.