Skip to content

Commit 5237b13

Browse files
wan9chicodex
andcommitted
fix(cache): raise cache preallocation limit
Co-authored-by: GPT-5.6 Codex <codex@openai.com>
1 parent 16429a5 commit 5237b13

2 files changed

Lines changed: 34 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Changelog
22

3+
- **Fixed** The task cache now supports much larger automatically tracked input sets without hitting wincode's default 4 MiB sequence preallocation limit ([#554](https://github.com/voidzero-dev/vite-task/pull/554)).
34
- **Fixed** npm workspace patterns beginning with `./` now discover matching packages correctly ([vite-plus#2201](https://github.com/voidzero-dev/vite-plus/issues/2201), [#547](https://github.com/voidzero-dev/vite-task/pull/547)).
45
- **Fixed** Failures while forwarding output from a started task process no longer incorrectly say the process failed to spawn ([#506](https://github.com/voidzero-dev/vite-task/issues/506)).
56
- **Fixed** An issue where Bun tasks on macOS did not rerun when files they read, wrote, or listed changed ([#532](https://github.com/voidzero-dev/vite-task/issues/532), [#542](https://github.com/voidzero-dev/vite-task/pull/542)).

crates/vite_task/src/session/cache/mod.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use vite_task_graph::config::ResolvedGlobConfig;
2020
use vite_task_plan::cache_metadata::{CacheMetadata, ExecutionCacheKey, SpawnFingerprint};
2121
use wincode::{
2222
SchemaRead, SchemaReadOwned, SchemaWrite,
23-
config::{ConfigCore, DefaultConfig},
23+
config::{ConfigCore, Configuration},
2424
error::{ReadResult, WriteResult},
2525
io::{Reader, Writer},
2626
};
@@ -30,6 +30,25 @@ use super::execute::{
3030
pipe::StdOutput,
3131
};
3232

33+
const TASK_CACHE_PREALLOCATION_SIZE_LIMIT: usize = 256 * 1024 * 1024;
34+
type TaskCacheConfig = Configuration<true, TASK_CACHE_PREALLOCATION_SIZE_LIMIT>;
35+
const TASK_CACHE_CONFIG: TaskCacheConfig =
36+
Configuration::default().with_preallocation_size_limit::<TASK_CACHE_PREALLOCATION_SIZE_LIMIT>();
37+
38+
fn serialize_cache<T>(value: &T) -> WriteResult<Vec<u8>>
39+
where
40+
T: SchemaWrite<TaskCacheConfig, Src = T> + ?Sized,
41+
{
42+
wincode::config::serialize(value, TASK_CACHE_CONFIG)
43+
}
44+
45+
fn deserialize_cache<T>(bytes: &[u8]) -> ReadResult<T>
46+
where
47+
T: SchemaReadOwned<TaskCacheConfig, Dst = T>,
48+
{
49+
wincode::config::deserialize_exact(bytes, TASK_CACHE_CONFIG)
50+
}
51+
3352
/// Cache lookup key identifying a task's execution configuration.
3453
///
3554
/// # Key vs value design
@@ -255,7 +274,7 @@ pub fn split_path(path: &str) -> (Option<&str>, &str) {
255274
/// its own cache warm across branch switches, and a cache from a different
256275
/// version is simply ignored (it lives in a directory this build never looks
257276
/// at) rather than aborting the run. Bumping the version starts a fresh cache.
258-
const CACHE_SCHEMA_VERSION: u32 = 17;
277+
const CACHE_SCHEMA_VERSION: u32 = 18;
259278

260279
/// Name of the per-version subdirectory (e.g. `v14`) under the task-cache
261280
/// directory that holds the database and output archives for the current
@@ -461,14 +480,14 @@ impl ExecutionCache {
461480
reason = "lock guard cannot be dropped earlier because prepared statement borrows connection"
462481
)]
463482
async fn get_key_by_value<
464-
K: SchemaWrite<DefaultConfig, Src = K>,
465-
V: SchemaReadOwned<DefaultConfig, Dst = V>,
483+
K: SchemaWrite<TaskCacheConfig, Src = K>,
484+
V: SchemaReadOwned<TaskCacheConfig, Dst = V>,
466485
>(
467486
&self,
468487
table: &str,
469488
key: &K,
470489
) -> anyhow::Result<Option<V>> {
471-
let key_blob = wincode::serialize(key)?;
490+
let key_blob = serialize_cache(key)?;
472491
let value_blob = {
473492
let conn = self.conn.lock().await;
474493
#[expect(
@@ -484,7 +503,7 @@ impl ExecutionCache {
484503
let Some(value_blob) = value_blob else {
485504
return Ok(None);
486505
};
487-
let value: V = wincode::deserialize(&value_blob)?;
506+
let value: V = deserialize_cache(&value_blob)?;
488507
Ok(Some(value))
489508
}
490509

@@ -507,16 +526,16 @@ impl ExecutionCache {
507526
reason = "lock guard must be held while executing the prepared statement"
508527
)]
509528
async fn upsert<
510-
K: SchemaWrite<DefaultConfig, Src = K>,
511-
V: SchemaWrite<DefaultConfig, Src = V>,
529+
K: SchemaWrite<TaskCacheConfig, Src = K>,
530+
V: SchemaWrite<TaskCacheConfig, Src = V>,
512531
>(
513532
&self,
514533
table: &str,
515534
key: &K,
516535
value: &V,
517536
) -> anyhow::Result<()> {
518-
let key_blob = wincode::serialize(key)?;
519-
let value_blob = wincode::serialize(value)?;
537+
let key_blob = serialize_cache(key)?;
538+
let value_blob = serialize_cache(value)?;
520539
let conn = self.conn.lock().await;
521540
#[expect(clippy::disallowed_macros, reason = "SQL query string for rusqlite requires String")]
522541
let mut update_stmt = conn.prepare_cached(&format!(
@@ -547,8 +566,8 @@ impl ExecutionCache {
547566
reason = "lock guard must be held while iterating over query rows"
548567
)]
549568
async fn list_table<
550-
K: SchemaReadOwned<DefaultConfig, Dst = K> + Serialize,
551-
V: SchemaReadOwned<DefaultConfig, Dst = V> + Serialize,
569+
K: SchemaReadOwned<TaskCacheConfig, Dst = K> + Serialize,
570+
V: SchemaReadOwned<TaskCacheConfig, Dst = V> + Serialize,
552571
>(
553572
&self,
554573
table: &str,
@@ -564,8 +583,8 @@ impl ExecutionCache {
564583
while let Some(row) = rows.next()? {
565584
let key_blob: Vec<u8> = row.get(0)?;
566585
let value_blob: Vec<u8> = row.get(1)?;
567-
let key: K = wincode::deserialize(&key_blob)?;
568-
let value: V = wincode::deserialize(&value_blob)?;
586+
let key: K = deserialize_cache(&key_blob)?;
587+
let value: V = deserialize_cache(&value_blob)?;
569588
writeln!(
570589
out,
571590
"{} => {}",

0 commit comments

Comments
 (0)