Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: enable receive multiplayer transactions #1930

Merged
merged 6 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions quadratic-client/src/app/web-workers/quadraticCore/worker/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,20 +316,26 @@ class Core {
this.clientQueue.push(async () => {
if (!this.gridController) throw new Error('Expected gridController to be defined');

for (let data of receive_transactions.transactions) {
// convert the base64 encoded string of operations into buffers
if (typeof data.operations === 'string') {
data.operations = Buffer.from(data.operations, 'base64');
}

this.gridController.multiplayerTransaction(data.id, data.sequence_num, new Uint8Array(data.operations));
}
let formattedTransactions = receive_transactions.transactions.map((transaction) => ({
id: transaction.id,
file_id: transaction.file_id,
sequence_num: transaction.sequence_num,
operations:
typeof transaction.operations === 'string'
? Array.from(Buffer.from(transaction.operations, 'base64'))
: Array.from(transaction.operations),
}));
receive_transactions.transactions = [];

// TODO(ayush): find a better way to do this, avoid JSON.stringify and pass the buffer directly
const transactionsBuffer = JSON.stringify(formattedTransactions);
formattedTransactions = [];

this.gridController.receiveMultiplayerTransactions(transactionsBuffer);

// sends multiplayer synced to the client, to proceed from file loading screen
coreClient.sendMultiplayerSynced();

// TODO(ddimaria): re-enable 5 - 7 days after we roll out the compressed
// transactions PR, so that we'll know all transactions are of the same version.
//
// const transactionsBuffer = JSON.stringify(receive_transactions.transactions);
// this.gridController.receiveMultiplayerTransactions(transactionsBuffer);
if (await offline.unsentTransactionsCount()) {
coreClient.sendMultiplayerState('syncing');
} else {
Expand Down
16 changes: 6 additions & 10 deletions quadratic-core/src/controller/execution/receive_multiplayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,7 @@ impl GridController {
);
}
}
}

if (cfg!(target_family = "wasm") || cfg!(test))
&& sequence_num >= self.transactions.last_sequence_num
{
} else if cfg!(target_family = "wasm") || cfg!(test) {
crate::wasm_bindings::js::jsMultiplayerSynced();
}
}
Expand Down Expand Up @@ -226,7 +222,7 @@ impl GridController {
}

/// Received transactions from the server
pub fn received_transactions(&mut self, transactions: &[TransactionServer]) {
pub fn received_transactions(&mut self, transactions: Vec<TransactionServer>) {
// used to track client changes when combining transactions
let results = PendingTransaction {
transaction_type: TransactionType::Multiplayer,
Expand All @@ -235,7 +231,7 @@ impl GridController {
self.rollback_unsaved_transactions();

// combine all transaction into one transaction
transactions.iter().for_each(|t| {
transactions.into_iter().for_each(|t| {
let operations =
Transaction::decompress_and_deserialize::<Vec<Operation>>(&t.operations);

Expand Down Expand Up @@ -689,7 +685,7 @@ mod tests {
// todo...
// assert_eq!(client_summary.request_transactions, Some(1));

client.received_transactions(&[
client.received_transactions(vec![
TransactionServer {
file_id: Uuid::new_v4(),
id: Uuid::new_v4(),
Expand Down Expand Up @@ -768,7 +764,7 @@ mod tests {
let transaction_id = client.async_transactions()[0].id;

// we receive the first transaction while waiting for the async call to complete
client.received_transactions(&[TransactionServer {
client.received_transactions(vec![TransactionServer {
file_id: Uuid::new_v4(),
id: Uuid::new_v4(),
sequence_num: 1,
Expand Down Expand Up @@ -865,7 +861,7 @@ mod tests {
let transaction_id = client.async_transactions()[0].id;

// we receive the first transaction while waiting for the async call to complete
client.received_transactions(&[TransactionServer {
client.received_transactions(vec![TransactionServer {
file_id: Uuid::new_v4(),
id: Uuid::new_v4(),
sequence_num: 1,
Expand Down
37 changes: 19 additions & 18 deletions quadratic-core/src/wasm_bindings/controller/transactions.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use super::*;
use crate::controller::{
active_transactions::unsaved_transactions::UnsavedTransaction,
operations::operation::Operation, transaction::Transaction,
operations::operation::Operation,
transaction::{Transaction, TransactionServer},
};
use uuid::Uuid;

Expand Down Expand Up @@ -44,23 +45,23 @@ impl GridController {
)?)
}

// TODO(ddimaria): re-enable 5 - 7 days after we roll out the compressed
// transactions PR, so that we'll know all transactions are of the same version.
//
// #[wasm_bindgen(js_name = "receiveMultiplayerTransactions")]
// pub fn js_receive_multiplayer_transactions(
// &mut self,
// transactions: &str,
// ) -> Result<JsValue, JsValue> {
// match serde_json::from_str::<Vec<TransactionServer>>(transactions) {
// Ok(transactions) => Ok(serde_wasm_bindgen::to_value(
// &self.received_transactions(&transactions[..]),
// )?),
// Err(e) => Err(JsValue::from_str(&format!(
// "Invalid transactions received in receiveMultiplayerTransactions: {e}"
// ))),
// }
// }
#[wasm_bindgen(js_name = "receiveMultiplayerTransactions")]
pub fn js_receive_multiplayer_transactions(
&mut self,
transactions: String,
) -> Result<JsValue, JsValue> {
match serde_json::from_str::<Vec<TransactionServer>>(&transactions) {
Ok(transactions) => Ok(serde_wasm_bindgen::to_value(
&self.received_transactions(transactions),
)?),
Err(e) => {
dbgjs!(format!("{transactions}"));
Err(JsValue::from_str(&format!(
"Invalid transactions received in receiveMultiplayerTransactions: {e}"
)))
}
}
}

#[wasm_bindgen(js_name = "applyOfflineUnsavedTransaction")]
pub fn js_apply_offline_unsaved_transaction(
Expand Down
Loading