mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
fix sync_db middleware
This commit is contained in:
@@ -11,7 +11,7 @@ use josekit::jwk::Jwk;
|
||||
use reqwest::{Client, Proxy};
|
||||
use rpc_toolkit::yajrc::RpcError;
|
||||
use rpc_toolkit::{CallRemote, Context, Empty};
|
||||
use tokio::sync::{broadcast, Mutex, RwLock};
|
||||
use tokio::sync::{broadcast, watch, Mutex, RwLock};
|
||||
use tokio::time::Instant;
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -43,6 +43,7 @@ pub struct RpcContextSeed {
|
||||
pub datadir: PathBuf,
|
||||
pub disk_guid: Arc<String>,
|
||||
pub db: TypedPatchDb<Database>,
|
||||
pub sync_db: watch::Sender<u64>,
|
||||
pub account: RwLock<AccountInfo>,
|
||||
pub net_controller: Arc<NetController>,
|
||||
pub s9pk_arch: Option<&'static str>,
|
||||
@@ -212,6 +213,7 @@ impl RpcContext {
|
||||
find_eth_iface().await?
|
||||
},
|
||||
disk_guid,
|
||||
sync_db: watch::Sender::new(db.sequence().await),
|
||||
db,
|
||||
account: RwLock::new(account),
|
||||
net_controller,
|
||||
|
||||
@@ -10,10 +10,12 @@ use clap::Parser;
|
||||
use imbl_value::InternedString;
|
||||
use itertools::Itertools;
|
||||
use patch_db::json_ptr::{JsonPointer, ROOT};
|
||||
use patch_db::{Dump, Revision};
|
||||
use patch_db::{DiffPatch, Dump, Revision};
|
||||
use rpc_toolkit::yajrc::RpcError;
|
||||
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::mpsc::{self, UnboundedReceiver};
|
||||
use tokio::sync::watch;
|
||||
use tracing::instrument;
|
||||
use ts_rs::TS;
|
||||
|
||||
@@ -124,14 +126,56 @@ pub struct SubscribeRes {
|
||||
pub guid: Guid,
|
||||
}
|
||||
|
||||
struct DbSubscriber {
|
||||
rev: u64,
|
||||
sub: UnboundedReceiver<Revision>,
|
||||
sync_db: watch::Receiver<u64>,
|
||||
}
|
||||
impl DbSubscriber {
|
||||
async fn recv(&mut self) -> Option<Revision> {
|
||||
loop {
|
||||
tokio::select! {
|
||||
rev = self.sub.recv() => {
|
||||
if let Some(rev) = rev.as_ref() {
|
||||
self.rev = rev.id;
|
||||
}
|
||||
return rev
|
||||
}
|
||||
_ = self.sync_db.changed() => {
|
||||
let id = *self.sync_db.borrow();
|
||||
if id > self.rev {
|
||||
match self.sub.try_recv() {
|
||||
Ok(rev) => {
|
||||
self.rev = rev.id;
|
||||
return Some(rev)
|
||||
}
|
||||
Err(mpsc::error::TryRecvError::Disconnected) => {
|
||||
return None
|
||||
}
|
||||
Err(mpsc::error::TryRecvError::Empty) => {
|
||||
return Some(Revision { id, patch: DiffPatch::default() })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn subscribe(
|
||||
ctx: RpcContext,
|
||||
SubscribeParams { pointer, session }: SubscribeParams,
|
||||
) -> Result<SubscribeRes, Error> {
|
||||
let (dump, mut sub) = ctx
|
||||
let (dump, sub) = ctx
|
||||
.db
|
||||
.dump_and_sub(pointer.unwrap_or_else(|| PUBLIC.clone()))
|
||||
.await;
|
||||
let mut sub = DbSubscriber {
|
||||
rev: dump.id,
|
||||
sub,
|
||||
sync_db: ctx.sync_db.subscribe(),
|
||||
};
|
||||
let guid = Guid::new();
|
||||
ctx.rpc_continuations
|
||||
.add(
|
||||
|
||||
@@ -36,10 +36,11 @@ impl Middleware<RpcContext> for SyncDb {
|
||||
async fn process_http_response(&mut self, context: &RpcContext, response: &mut Response) {
|
||||
if let Err(e) = async {
|
||||
if self.sync_db {
|
||||
response.headers_mut().append(
|
||||
"X-Patch-Sequence",
|
||||
HeaderValue::from_str(&context.db.sequence().await.to_string())?,
|
||||
);
|
||||
let id = context.db.sequence().await;
|
||||
response
|
||||
.headers_mut()
|
||||
.append("X-Patch-Sequence", HeaderValue::from_str(&id.to_string())?);
|
||||
context.sync_db.send_replace(id);
|
||||
}
|
||||
Ok::<_, InvalidHeaderValue>(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user