Skip to content

Commit cad1217

Browse files
committed
Remove stale files in changes producer.
1 parent 020be3c commit cad1217

File tree

1 file changed

+48
-24
lines changed

1 file changed

+48
-24
lines changed

crates/changes/src/producer.rs

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
use crate::{Error, Result};
33
use futures::sink::SinkExt;
44
use interprocess::local_socket::{tokio::prelude::*, GenericNamespaced};
5-
use sos_core::{events::changes_feed, Paths};
6-
use std::{sync::Arc, time::Duration};
5+
use sos_core::{
6+
events::{changes_feed, LocalChangeEvent},
7+
Paths,
8+
};
9+
use std::{path::PathBuf, sync::Arc, time::Duration};
710
use tokio::{
811
select,
912
sync::{watch, Mutex},
@@ -59,41 +62,26 @@ impl ChangeProducer {
5962
loop {
6063
let paths = paths.clone();
6164
select! {
65+
// Explicit cancel notification
6266
_ = cancel_rx.changed() => {
6367
if *cancel_rx.borrow_and_update() {
6468
break;
6569
}
6670
}
71+
// Periodically refresh the list of consumer sockets
72+
// to dispatch change events to
6773
_ = interval.tick() => {
6874
let active = find_active_sockets(paths).await?;
6975
let mut sockets = sockets.lock().await;
7076
*sockets = active;
7177
}
78+
// Proxy the change events to the consumer sockets
7279
event = rx.changed() => {
7380
match event {
7481
Ok(_) => {
7582
let event = rx.borrow_and_update().clone();
7683
let sockets = sockets.lock().await;
77-
for pid in &*sockets {
78-
let ps_name = pid.to_string();
79-
let name = ps_name.to_ns_name::<GenericNamespaced>()?;
80-
match LocalSocketStream::connect(name).await {
81-
Ok(socket) => {
82-
let mut writer =
83-
LengthDelimitedCodec::builder()
84-
.native_endian()
85-
.new_write(socket);
86-
let message = serde_json::to_vec(&event)?;
87-
writer.send(message.into()).await?;
88-
}
89-
Err(e) => {
90-
tracing::warn!(
91-
pid = %pid,
92-
error = %e,
93-
"changes::producer::connect_error");
94-
}
95-
}
96-
}
84+
dispatch_sockets(event, &*sockets).await?;
9785
}
9886
Err(_) => {}
9987
}
@@ -106,8 +94,44 @@ impl ChangeProducer {
10694
}
10795
}
10896

97+
async fn dispatch_sockets(
98+
event: LocalChangeEvent,
99+
sockets: &[(u32, PathBuf)],
100+
) -> Result<()> {
101+
for (pid, file) in sockets {
102+
let ps_name = pid.to_string();
103+
let name = ps_name.to_ns_name::<GenericNamespaced>()?;
104+
match LocalSocketStream::connect(name).await {
105+
Ok(socket) => {
106+
let mut writer = LengthDelimitedCodec::builder()
107+
.native_endian()
108+
.new_write(socket);
109+
let message = serde_json::to_vec(&event)?;
110+
writer.send(message.into()).await?;
111+
}
112+
Err(e) => {
113+
// If we can't connect to the socket
114+
// then treat the file as stale and
115+
// remove from disc.
116+
//
117+
// This could happen if the consumer
118+
// process aborted abnormally and
119+
// wasn't able to cleanly remove the file.
120+
let _ = std::fs::remove_file(file)?;
121+
tracing::warn!(
122+
pid = %pid,
123+
error = %e,
124+
"changes::producer::connect_error");
125+
}
126+
}
127+
}
128+
Ok(())
129+
}
130+
109131
/// Find active socket files for a producer.
110-
async fn find_active_sockets(paths: Arc<Paths>) -> Result<Vec<u32>> {
132+
async fn find_active_sockets(
133+
paths: Arc<Paths>,
134+
) -> Result<Vec<(u32, PathBuf)>> {
111135
use std::fs::read_dir;
112136
let mut sockets = Vec::new();
113137
let socks = paths.documents_dir().join(crate::SOCKS);
@@ -126,7 +150,7 @@ async fn find_active_sockets(paths: Arc<Paths>) -> Result<Vec<u32>> {
126150
sock_file_pid = %pid,
127151
"changes::producer::find_active_sockets",
128152
);
129-
sockets.push(pid);
153+
sockets.push((pid, entry.path().to_owned()));
130154
}
131155
}
132156
}

0 commit comments

Comments
 (0)