Skip to content

Commit dcba9ea

Browse files
committed
Created proof-of-concept for saving cache to disk
1 parent 0aff301 commit dcba9ea

File tree

19 files changed

+179
-93
lines changed

19 files changed

+179
-93
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/daemon/src/server.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ pub fn server_main(max_idle_time: Duration) -> io::Result<()> {
4949
}
5050
}
5151

52+
// Try to save the cache to disk before we exit if possible
53+
if rt.lock().await.cache_to_disk {
54+
let _ = rt.lock().await.cache().save("adept.cache");
55+
}
56+
5257
Ok(())
5358
})
5459
}

src/components/daemon/src/watch.rs

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -52,74 +52,80 @@ pub async fn watch<'e, P: Pf, REQ: Into<P::Req<'e>> + Clone + Send + UnwrapAft<'
5252
// NOTE: We keep the lock acquired for the entire lifetime of the query
5353
let mut rt = rt.lock().await;
5454

55-
let run = async {
56-
// Read the new project while we're at it. This will likely have already been computed.
57-
let new_project = watch_query(
58-
rt.deref_mut(),
59-
GetProject {
60-
working_directory: working_directory.clone(),
61-
},
62-
QueryMode::Continue,
63-
TimeoutAt(Instant::now() + Duration::from_millis(50)),
64-
)
65-
.await;
66-
67-
// Determine if the watch config was changed as part of the project config.
68-
let new_watch_config = match new_project {
69-
Ok(BlockOn::Complete(Ok(project))) => {
70-
let config = WatchConfig {
71-
interval_ms: project.interval_ms.unwrap_or(DEFAULTS.interval_ms),
72-
cache_to_disk: project.cache_to_disk.unwrap_or(DEFAULTS.cache_to_disk),
73-
max_idle_time_ms: project.max_idle_time_ms,
74-
};
75-
76-
(config != watch_config).then_some(config)
77-
}
78-
Ok(BlockOn::Complete(Err(errors)))
79-
if !errors
80-
.iter_unordered()
81-
.any(|error| error.is_invalid_project_config_syntax()) =>
82-
{
83-
// Failed to parse project file, don't change the configuration
84-
None
85-
}
86-
_ => {
87-
// Failed to read project file
88-
(watch_config != DEFAULTS).then_some(DEFAULTS)
89-
}
90-
};
55+
// Read the new project while we're at it.
56+
let new_project = watch_query(
57+
rt.deref_mut(),
58+
GetProject {
59+
working_directory: working_directory.clone(),
60+
},
61+
QueryMode::New,
62+
TimeoutAt(Instant::now() + Duration::from_millis(50)),
63+
)
64+
.await;
65+
66+
// Determine if the watch config was changed as part of the project config.
67+
let new_watch_config = match new_project {
68+
Ok(BlockOn::Complete(Ok(project))) => {
69+
let config = WatchConfig {
70+
interval_ms: project.interval_ms.unwrap_or(DEFAULTS.interval_ms),
71+
cache_to_disk: project.cache_to_disk.unwrap_or(DEFAULTS.cache_to_disk),
72+
max_idle_time_ms: project.max_idle_time_ms,
73+
};
74+
75+
(config != watch_config).then_some(config)
76+
}
77+
Ok(BlockOn::Complete(Err(errors)))
78+
if !errors
79+
.iter_unordered()
80+
.any(|error| error.is_invalid_project_config_syntax()) =>
81+
{
82+
// Failed to parse project file, don't change the configuration
83+
None
84+
}
85+
_ => {
86+
// Failed to read project file
87+
(watch_config != DEFAULTS).then_some(DEFAULTS)
88+
}
89+
};
9190

92-
// If we have a new watch config, update it as well as the idle tracker.
93-
if let Some(new_watch_config) = new_watch_config {
94-
watch_config = new_watch_config;
91+
// If we have a new watch config, update it as well as the idle tracker.
92+
if let Some(new_watch_config) = new_watch_config {
93+
watch_config = new_watch_config;
9594

96-
let mut idle_tracker = server.idle_tracker.lock().await;
97-
idle_tracker.last_active = Instant::now();
98-
idle_tracker
99-
.set_max_idle_time(watch_config.max_idle_time_ms.map(Duration::from_millis));
100-
}
95+
let mut idle_tracker = server.idle_tracker.lock().await;
96+
idle_tracker.last_active = Instant::now();
97+
idle_tracker
98+
.set_max_idle_time(watch_config.max_idle_time_ms.map(Duration::from_millis));
99+
rt.cache_to_disk = watch_config.cache_to_disk;
100+
}
101101

102+
let run = async {
102103
let timeout = TimeoutAt(Instant::now() + Duration::from_secs(2));
103-
Ok(watch_query(rt.deref_mut(), watchee.clone(), QueryMode::New, timeout).await)
104+
Ok(watch_query(
105+
rt.deref_mut(),
106+
watchee.clone(),
107+
QueryMode::Continue,
108+
timeout,
109+
)
110+
.await)
104111
};
105112

106113
let timeout = async {
107114
Timer::after(Duration::from_millis(500)).await;
108115
Err(())
109116
};
110117

118+
if server.idle_tracker.lock().await.shutdown_if_idle() {
119+
break;
120+
}
121+
111122
log!("Watch Result is {:?}", run.or(timeout).await);
112123
Timer::after(Duration::from_millis(watch_config.interval_ms)).await;
113124

114125
if server.idle_tracker.lock().await.shutdown_if_idle() {
115126
break;
116127
}
117128
}
118-
119-
// Try to save the cache to disk before we exit if possible
120-
if watch_config.cache_to_disk {
121-
let _ = rt.lock().await.cache().save("adept.cache");
122-
}
123129
}
124130

125131
async fn watch_query<

src/components/req/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ infinite_iterator = { version = "0.1.0", path = "../../support/infinite_iterator
1515
line_column = { version = "0.1.0", path = "../../support/line_column" }
1616
serde = { version = "1.0.228", features = ["derive", "rc"] }
1717
serde_json = "1.0.145"
18-
smallvec = "1.15.1"
18+
smallvec = { version = "1.15.1", features = ["serde"] }
1919
text = { version = "0.1.0", path = "../../support/text" }
2020
thiserror = "2.0.17"
2121
token = { version = "0.1.0", path = "../../representations/token" }

src/components/req/src/errors.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use derive_more::IsVariant;
2+
use serde::{Deserialize, Serialize};
23
use std::sync::Arc;
34
use thiserror::Error;
45

5-
#[derive(Clone, Debug, Error, Hash, PartialEq, Eq, PartialOrd, Ord, IsVariant)]
6+
#[derive(
7+
Clone, Debug, Error, Hash, PartialEq, Eq, PartialOrd, Ord, IsVariant, Serialize, Deserialize,
8+
)]
69
pub enum Error {
710
#[error("Missing project file `adept.build`")]
811
MissingProjectFile,

src/components/req/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub use pf::*;
2323
pub use requests::*;
2424
pub use rt::*;
2525
pub use rt_st_in::*;
26+
use serde::{Deserialize, Serialize};
2627
use std::{path::Path, sync::Arc};
2728
pub use succ::*;
2829
pub use syms::*;
@@ -41,7 +42,7 @@ macro_rules! log {
4142
}};
4243
}
4344

44-
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
45+
#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
4546
pub struct Project {
4647
pub root: Arc<Path>,
4748
pub interval_ms: Option<u64>,
@@ -71,10 +72,11 @@ mod requests {
7172
pub struct GetProjectState;
7273

7374
#[define_requests::returns(String)]
74-
pub struct Search<'e>(&'e str);
75+
pub struct Search();
7576
#[derive(Default)]
7677
pub struct SearchState;
7778

79+
#[define_requests::never_persist]
7880
#[define_requests::returns(WithErrors<Syms<P>>)]
7981
pub struct Approach;
8082
#[derive(Default)]

src/components/req/src/like.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub trait Like<T> {
66
fn like_mut(&mut self) -> &mut T;
77
}
88

9-
impl<'e> Like<Req<'e>> for Req<'e> {
9+
impl<'e> Like<Req> for Req {
1010
#[inline(always)]
1111
fn like(self) -> Self {
1212
self

src/components/req/src/pf.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use crate::{Aft, Approach, AsSyms, IsDiv, IsImpure, Like, Minor, Req, RunDispatch, St, UnLike};
1+
use crate::{
2+
Aft, Approach, AsSyms, IsDiv, IsImpure, Like, Minor, Req, RunDispatch, ShouldPersist, St,
3+
UnLike,
4+
};
5+
use serde::{Deserialize, Serialize};
26
use std::{fmt::Debug, hash::Hash};
37

48
pub trait Pf: Clone + Debug + Default {
@@ -9,9 +13,12 @@ pub trait Pf: Clone + Debug + Default {
913
+ Eq
1014
+ Send
1115
+ IsImpure
16+
+ ShouldPersist
1217
+ From<Approach>
1318
+ RunDispatch<'e, Self>
14-
+ UnLike<Req<'e>>;
19+
+ UnLike<Req>
20+
+ Serialize
21+
+ Deserialize<'e>;
1522
type Rev: Copy
1623
+ Clone
1724
+ Debug
@@ -22,7 +29,17 @@ pub trait Pf: Clone + Debug + Default {
2229
+ Ord
2330
+ Send
2431
+ IsDiv
25-
+ Minor;
26-
type Aft<'e>: Debug + Clone + Send + AsSyms<Self> + PartialEq + Eq + Like<Aft<Self>>;
32+
+ Minor
33+
+ Serialize
34+
+ for<'de> Deserialize<'de>;
35+
type Aft<'e>: Debug
36+
+ Clone
37+
+ Send
38+
+ AsSyms<Self>
39+
+ PartialEq
40+
+ Eq
41+
+ Like<Aft<Self>>
42+
+ Serialize
43+
+ Deserialize<'e>;
2744
type St<'e>: Debug + Default + Send + Like<St>;
2845
}

src/components/req/src/rt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ pub trait Rt<'e, P: Pf>: Send {
2222

2323
pub trait Th<'e, P: Pf>
2424
where
25-
P::Req<'e>: UnLike<Req<'e>>,
25+
P::Req<'e>: UnLike<Req>,
2626
{
2727
type Rt: Rt<'e, P>;
2828
fn rt(&self) -> &Self::Rt;
2929
fn demand<R>(&mut self, req: R) -> Result<&R::Aft<'e>, Suspend>
3030
where
31-
R: Into<Req<'e>> + UnwrapAft<'e, P>;
31+
R: Into<Req> + UnwrapAft<'e, P>;
3232
}
3333

3434
pub trait Ch<'e, P: Pf> {

src/components/req/src/rt_st_in/cache.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use crate::{Pf, TaskStatus};
2-
use serde::ser::SerializeMap;
1+
use crate::{Pf, ShouldPersist, TaskStatus, TaskStatusKind};
2+
use serde::ser::{SerializeMap, SerializeSeq};
33
use std::{collections::HashMap, io::Write, path::Path};
44

55
const HEADER: &[u8] =
66
b"This file is a local cache and *not* sharable. It should be ignored for version control purposes.\n";
77
const COMPILER_BUILT_AT: u64 = compile_time::unix!();
8-
const HUMAN_READABLE: bool = true;
8+
const HUMAN_READABLE: bool = false;
99

1010
#[derive(Default)]
1111
pub struct Cache<'e, P: Pf> {
@@ -66,8 +66,29 @@ impl<'e, P: Pf> serde::Serialize for Kv<'e, P> {
6666
where
6767
S: serde::Serializer,
6868
{
69-
let map = serializer.serialize_map(Some(0))?;
70-
map.end()
69+
let mut include = vec![];
70+
71+
for (key, value) in self.inner.iter() {
72+
if !key.should_persist() {
73+
continue;
74+
}
75+
match value {
76+
Some(status) => match &status.kind {
77+
TaskStatusKind::Running(_) => (),
78+
TaskStatusKind::Completed(completed) => {
79+
include.push((key, &completed.aft));
80+
}
81+
TaskStatusKind::Restarting(_) => (),
82+
},
83+
None => (),
84+
}
85+
}
86+
87+
let mut seq = serializer.serialize_seq(Some(include.len()))?;
88+
for entry in include {
89+
seq.serialize_element(&entry)?;
90+
}
91+
seq.end()
7192
}
7293
}
7394

0 commit comments

Comments
 (0)