feat(sync): add typed acknowledgement effect
req: sync/006
This commit is contained in:
@@ -15,7 +15,7 @@ use hemx_axum::{
|
||||
use hemx_kanban_example::ui::board::{self as board};
|
||||
use hemx_kanban_example::ui::board_card as card_board;
|
||||
use hemx_kanban_example::ui::{self, board as board_ui};
|
||||
use hemx_sync::{Channel, PresenceScope, PresenceTracker, PresenceUpdate};
|
||||
use hemx_sync::{Channel, PresenceScope, PresenceTracker, PresenceUpdate, SyncEffect};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::Infallible;
|
||||
@@ -502,6 +502,7 @@ async fn main() {
|
||||
.route("/", get(home).post(interact))
|
||||
.route("/events", get(events))
|
||||
.route("/sync/broadcast", get(sync_broadcast))
|
||||
.route("/sync/ack", get(sync_ack))
|
||||
.route("/sync-demo", get(sync_demo))
|
||||
.route("/sync.js", get(sync_js))
|
||||
.route("/sync/context", get(sync_context))
|
||||
@@ -601,6 +602,39 @@ fn presence_changed(signal: PresenceSignal) -> impl hemx::IntoEffect {
|
||||
})
|
||||
}
|
||||
|
||||
async fn sync_ack(
|
||||
State(state): State<Arc<AppState>>,
|
||||
headers: HeaderMap,
|
||||
Query(params): Query<BTreeMap<String, String>>,
|
||||
) -> Result<Response, SyncRejection> {
|
||||
let principal = current_sync_principal(&headers, &state.sync_sessions)?;
|
||||
let command_id = CommandId::parse(params.get("command_id"))?;
|
||||
let acknowledgement = {
|
||||
let sync = state.sync.lock().unwrap();
|
||||
let acknowledgement =
|
||||
sync.acknowledgements
|
||||
.get(&command_id)
|
||||
.ok_or(SyncRejection::Conflict(
|
||||
"command has no canonical acknowledgement",
|
||||
))?;
|
||||
if !visible_acknowledgement(principal, acknowledgement) {
|
||||
return Err(SyncRejection::Forbidden(
|
||||
"current tenant cannot access command acknowledgement",
|
||||
));
|
||||
}
|
||||
acknowledgement.clone()
|
||||
};
|
||||
let batch = (
|
||||
SyncEffect::ack(board::atoms::sync_ack),
|
||||
board::sync_status.text(format!(
|
||||
"Canonical acknowledgement {} at server sequence {}",
|
||||
acknowledgement.command_id, acknowledgement.server_sequence
|
||||
)),
|
||||
)
|
||||
.into_batch(ui::BUILD_FINGERPRINT);
|
||||
Ok(sse(stream::iter([Ok::<_, Infallible>(batch)]).boxed()).into_response())
|
||||
}
|
||||
|
||||
async fn sync_broadcast(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Query(params): Query<BTreeMap<String, String>>,
|
||||
|
||||
Reference in New Issue
Block a user