Skip to content

Commit b0a7019

Browse files
committed
fix: ignore disableCache in client
1 parent 8961354 commit b0a7019

8 files changed

Lines changed: 116 additions & 57 deletions

File tree

crates/vite_task_bin/tests/e2e_snapshots/fixtures/ipc_client_test/snapshots.toml

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -225,52 +225,55 @@ steps = [
225225
]
226226

227227
[[e2e]]
228-
name = "disable_cache_forces_reexecution"
228+
name = "disable_cache_noop_allows_cache_hit"
229229
comment = """
230-
Exercises `disableCache`. The tool asks the runner not to cache this run,
231-
so the next invocation re-executes instead of hitting a prior entry.
230+
Exercises the temporary `disableCache` no-op workaround. The tool asks the
231+
runner not to cache this run, but the client ignores that request, so the next
232+
invocation hits the cache.
232233
"""
233234
ignore = true
234235
steps = [
235236
{ argv = [
236237
"vt",
237238
"run",
238239
"disable-cache",
239-
], comment = "first run — tool calls disableCache" },
240+
], comment = "first run — tool calls disableCache, currently ignored by the client" },
240241
{ argv = [
241242
"vt",
242243
"run",
243244
"disable-cache",
244-
], comment = "cache miss (NotFound) because nothing was cached" },
245+
], comment = "cache hit because disableCache is temporarily a no-op" },
245246
{ argv = [
246247
"vt",
247248
"run",
248249
"--last-details",
249-
], comment = "summary names the opt-out as the not-cached reason" },
250+
], comment = "summary reports the replayed cache hit" },
250251
]
251252

252253
[[e2e]]
253-
name = "disable_cache_works_with_explicit_inputs"
254+
name = "disable_cache_noop_with_explicit_inputs"
254255
comment = """
255-
Exercises `disableCache` on a cached task with explicit inputs. The runner must still inject IPC even when fspy auto-input inference is disabled, or the tool's cache opt-out becomes a no-op and the second run incorrectly hits.
256+
Exercises the temporary `disableCache` no-op workaround on a cached task with
257+
explicit inputs. The client ignores the opt-out request, so the second run hits
258+
even when fspy auto-input inference is disabled.
256259
"""
257260
ignore = true
258261
steps = [
259262
{ argv = [
260263
"vt",
261264
"run",
262265
"disable-cache-explicit-input",
263-
], comment = "first run uses input: [] and asks the runner not to cache" },
266+
], comment = "first run uses input: [] and calls disableCache, currently ignored by the client" },
264267
{ argv = [
265268
"vt",
266269
"run",
267270
"disable-cache-explicit-input",
268-
], comment = "re-executes because the first run was not cached" },
271+
], comment = "cache hit because disableCache is temporarily a no-op" },
269272
{ argv = [
270273
"vt",
271274
"run",
272275
"--last-details",
273-
], comment = "summary names the opt-out as the not-cached reason" },
276+
], comment = "summary reports the replayed cache hit" },
274277
]
275278

276279
[[e2e]]

crates/vite_task_bin/tests/e2e_snapshots/fixtures/ipc_client_test/snapshots/disable_cache_forces_reexecution.md renamed to crates/vite_task_bin/tests/e2e_snapshots/fixtures/ipc_client_test/snapshots/disable_cache_noop_allows_cache_hit.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,44 @@
1-
# disable_cache_forces_reexecution
1+
# disable_cache_noop_allows_cache_hit
22

3-
Exercises `disableCache`. The tool asks the runner not to cache this run,
4-
so the next invocation re-executes instead of hitting a prior entry.
3+
Exercises the temporary `disableCache` no-op workaround. The tool asks the
4+
runner not to cache this run, but the client ignores that request, so the next
5+
invocation hits the cache.
56

67
## `vt run disable-cache`
78

8-
first run — tool calls disableCache
9+
first run — tool calls disableCache, currently ignored by the client
910

1011
```
1112
$ node scripts/disable_cache.mjs
1213
```
1314

1415
## `vt run disable-cache`
1516

16-
cache miss (NotFound) because nothing was cached
17+
cache hit because disableCache is temporarily a no-op
1718

1819
```
19-
$ node scripts/disable_cache.mjs
20+
$ node scripts/disable_cache.mjs ◉ cache hit, replaying
21+
22+
---
23+
vt run: cache hit.
2024
```
2125

2226
## `vt run --last-details`
2327

24-
summary names the opt-out as the not-cached reason
28+
summary reports the replayed cache hit
2529

2630
```
2731
2832
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2933
Vite+ Task Runner • Execution Summary
3034
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3135
32-
Statistics: 1 tasks • 0 cache hits • 1 cache misses
33-
Performance: 0% cache hit rate
36+
Statistics: 1 tasks • 1 cache hits • 0 cache misses
37+
Performance: 100% cache hit rate
3438
3539
Task Details:
3640
────────────────────────────────────────────────
3741
[1] ipc-client-test#disable-cache: $ node scripts/disable_cache.mjs ✓
38-
Not cached: the task opted out of caching
42+
Cache hit - output replayed -
3943
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4044
```

crates/vite_task_bin/tests/e2e_snapshots/fixtures/ipc_client_test/snapshots/disable_cache_works_with_explicit_inputs.md renamed to crates/vite_task_bin/tests/e2e_snapshots/fixtures/ipc_client_test/snapshots/disable_cache_noop_with_explicit_inputs.md

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,44 @@
1-
# disable_cache_works_with_explicit_inputs
1+
# disable_cache_noop_with_explicit_inputs
22

3-
Exercises `disableCache` on a cached task with explicit inputs. The runner must still inject IPC even when fspy auto-input inference is disabled, or the tool's cache opt-out becomes a no-op and the second run incorrectly hits.
3+
Exercises the temporary `disableCache` no-op workaround on a cached task with
4+
explicit inputs. The client ignores the opt-out request, so the second run hits
5+
even when fspy auto-input inference is disabled.
46

57
## `vt run disable-cache-explicit-input`
68

7-
first run uses input: [] and asks the runner not to cache
9+
first run uses input: [] and calls disableCache, currently ignored by the client
810

911
```
1012
$ node scripts/disable_cache.mjs
1113
```
1214

1315
## `vt run disable-cache-explicit-input`
1416

15-
re-executes because the first run was not cached
17+
cache hit because disableCache is temporarily a no-op
1618

1719
```
18-
$ node scripts/disable_cache.mjs
20+
$ node scripts/disable_cache.mjs ◉ cache hit, replaying
21+
22+
---
23+
vt run: cache hit.
1924
```
2025

2126
## `vt run --last-details`
2227

23-
summary names the opt-out as the not-cached reason
28+
summary reports the replayed cache hit
2429

2530
```
2631
2732
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
2833
Vite+ Task Runner • Execution Summary
2934
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3035
31-
Statistics: 1 tasks • 0 cache hits • 1 cache misses
32-
Performance: 0% cache hit rate
36+
Statistics: 1 tasks • 1 cache hits • 0 cache misses
37+
Performance: 100% cache hit rate
3338
3439
Task Details:
3540
────────────────────────────────────────────────
3641
[1] ipc-client-test#disable-cache-explicit-input: $ node scripts/disable_cache.mjs ✓
37-
Not cached: the task opted out of caching
42+
Cache hit - output replayed -
3843
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3944
```
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
[[e2e]]
2-
name = "vite_dev_disables_cache"
2+
name = "vite_dev_disable_cache_noop_allows_cache_hit"
33
comment = """
4-
`vt run --cache dev` brings up a Vite dev server programmatically on an ephemeral port and closes it immediately. Vite's `_createServer` calls `disableCache()` via `@voidzero-dev/vite-task-client`, so this run is never stored — the next invocation re-executes (cache miss / NotFound).
4+
`vt run --cache dev` brings up a Vite dev server programmatically on an
5+
ephemeral port and closes it immediately. Vite calls `disableCache()` via
6+
`@voidzero-dev/vite-task-client`, but the client temporarily ignores that
7+
request, so the next invocation hits the cache.
58
"""
69
ignore = true
710
steps = [
@@ -10,11 +13,11 @@ steps = [
1013
"run",
1114
"--cache",
1215
"dev",
13-
], comment = "first run — Vite dev start calls disableCache" },
16+
], comment = "first run — Vite dev calls disableCache, currently ignored by the client" },
1417
{ argv = [
1518
"vt",
1619
"run",
1720
"--cache",
1821
"dev",
19-
], comment = "cache miss (NotFound) because the first run was not stored" },
22+
], comment = "cache hit because disableCache is temporarily a no-op" },
2023
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# vite_dev_disable_cache_noop_allows_cache_hit
2+
3+
`vt run --cache dev` brings up a Vite dev server programmatically on an
4+
ephemeral port and closes it immediately. Vite calls `disableCache()` via
5+
`@voidzero-dev/vite-task-client`, but the client temporarily ignores that
6+
request, so the next invocation hits the cache.
7+
8+
## `vt run --cache dev`
9+
10+
first run — Vite dev calls disableCache, currently ignored by the client
11+
12+
```
13+
$ node dev.mjs
14+
```
15+
16+
## `vt run --cache dev`
17+
18+
cache hit because disableCache is temporarily a no-op
19+
20+
```
21+
$ node dev.mjs ◉ cache hit, replaying
22+
23+
---
24+
vt run: cache hit.
25+
```

crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite_dev_disable_cache/snapshots/vite_dev_disables_cache.md

Lines changed: 0 additions & 19 deletions
This file was deleted.

crates/vite_task_client/src/lib.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,24 @@ impl Client {
8484
self.send(&Request::IgnoreOutput(&ns))
8585
}
8686

87-
/// Fire-and-forget — see [`Self::ignore_input`].
87+
/// Temporary no-op.
88+
///
89+
/// `disableCache` currently causes too many false opt-outs because tools
90+
/// call it during configuration, before they know whether they will start
91+
/// an uncached operation such as listening on a port or watching the
92+
/// filesystem.
8893
///
8994
/// # Errors
9095
///
91-
/// Returns an error if the request fails to send.
96+
/// This temporary no-op does not currently return errors.
97+
#[expect(
98+
clippy::missing_const_for_fn,
99+
clippy::unnecessary_wraps,
100+
clippy::unused_self,
101+
reason = "temporary no-op preserves the public API until disableCache semantics are redesigned"
102+
)]
92103
pub fn disable_cache(&self) -> io::Result<()> {
93-
self.send(&Request::DisableCache)
104+
Ok(())
94105
}
95106

96107
/// Requests an env value from the runner. Returns `None` if the runner

crates/vite_task_server/tests/integration.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type RawStream = std::fs::File;
1414
use rustc_hash::FxHashMap;
1515
use tokio::runtime::Builder;
1616
use vite_task_client::{Client, GetEnvsQuery};
17-
use vite_task_ipc_shared::Request;
17+
use vite_task_ipc_shared::{GetEnvResponse, Request};
1818
use vite_task_server::{EnvQuery, Error, Recorder, Reports, ServerHandle, serve};
1919

2020
fn env_map(pairs: &[(&str, &str)]) -> FxHashMap<Arc<OsStr>, Arc<OsStr>> {
@@ -82,6 +82,15 @@ fn send_frame(stream: &mut RawStream, request: &Request<'_>) {
8282
stream.flush().expect("flush");
8383
}
8484

85+
fn recv_get_env_response(stream: &mut RawStream) -> GetEnvResponse {
86+
let mut len_bytes = [0u8; 4];
87+
stream.read_exact(&mut len_bytes).expect("read len");
88+
let len = u32::from_le_bytes(len_bytes) as usize;
89+
let mut buf = vec![0; len];
90+
stream.read_exact(&mut buf).expect("read body");
91+
wincode::deserialize_exact(&buf).expect("deserialize response")
92+
}
93+
8594
#[test]
8695
fn single_client_fire_and_forget() {
8796
#[cfg(unix)]
@@ -93,6 +102,9 @@ fn single_client_fire_and_forget() {
93102
let client = connect(&envs);
94103
client.ignore_input(OsStr::new(in_path)).unwrap();
95104
client.ignore_output(OsStr::new(out_path)).unwrap();
105+
// Temporary workaround: the client currently ignores disableCache so
106+
// tools cannot opt out at configuration time before they perform the
107+
// operation that actually makes a task uncacheable.
96108
client.disable_cache().unwrap();
97109
flush(&client);
98110
})
@@ -102,6 +114,21 @@ fn single_client_fire_and_forget() {
102114
let outputs: Vec<_> = reports.ignored_outputs.iter().map(|p| p.as_path().as_os_str()).collect();
103115
assert_eq!(inputs, vec![OsStr::new(in_path)]);
104116
assert_eq!(outputs, vec![OsStr::new(out_path)]);
117+
assert!(!reports.cache_disabled);
118+
}
119+
120+
#[test]
121+
fn raw_disable_cache_request_disables_cache() {
122+
let reports = run_with_server(env_map(&[]), |envs| {
123+
let name = &envs[0].1;
124+
let mut stream = connect_raw(name);
125+
send_frame(&mut stream, &Request::DisableCache);
126+
let flush_name: Box<NativeStr> = OsStr::new("__VP_TEST_FLUSH__").into();
127+
send_frame(&mut stream, &Request::GetEnv { name: &flush_name, tracked: false });
128+
let _ = recv_get_env_response(&mut stream);
129+
})
130+
.expect("driver returned error");
131+
105132
assert!(reports.cache_disabled);
106133
}
107134

0 commit comments

Comments
 (0)