Skip to content

Commit 5e2c4a8

Browse files
ldanilekConvex, Inc.
authored andcommitted
use SourcePackageId instead of ModuleVersion as cache key (#26934)
in my bid to get rid of module versions, we can now start using source package id as the key for cache lookups. this is more reliable because source packages don't disappear when the module gets updated. and once we do this we can allow REPL lookups to go through the cache. without the package id change, we can't because REPL module version might conflict with a real module version, but the package ids won't conflict. GitOrigin-RevId: a4429407817c8fe1e2eda998c3f0ac06bbb19551
1 parent 7cf57b3 commit 5e2c4a8

File tree

7 files changed

+29
-79
lines changed

7 files changed

+29
-79
lines changed

crates/application/src/module_cache/mod.rs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,14 @@ use keybroker::Identity;
2020
use model::{
2121
config::module_loader::ModuleLoader,
2222
modules::{
23-
module_versions::{
24-
FullModuleSource,
25-
ModuleVersion,
26-
},
23+
module_versions::FullModuleSource,
2724
types::ModuleMetadata,
2825
ModuleModel,
29-
MODULE_VERSIONS_TABLE,
3026
},
27+
source_packages::types::SourcePackageId,
3128
};
3229
use storage::Storage;
33-
use value::{
34-
ResolvedDocumentId,
35-
TableNamespace,
36-
};
30+
use value::ResolvedDocumentId;
3731

3832
mod metrics;
3933

@@ -43,7 +37,7 @@ pub struct ModuleCache<RT: Runtime> {
4337

4438
modules_storage: Arc<dyn Storage>,
4539

46-
cache: AsyncLru<RT, (ResolvedDocumentId, ModuleVersion), FullModuleSource>,
40+
cache: AsyncLru<RT, (ResolvedDocumentId, SourcePackageId), FullModuleSource>,
4741
}
4842

4943
impl<RT: Runtime> ModuleCache<RT> {
@@ -73,20 +67,7 @@ impl<RT: Runtime> ModuleLoader<RT> for ModuleCache<RT> {
7367
) -> anyhow::Result<Arc<FullModuleSource>> {
7468
let timer = metrics::module_cache_get_module_timer();
7569

76-
// If this transaction wrote to module_versions (true for REPLs), we cannot use
77-
// the cache, load the module directly.
78-
let module_versions_table_id = tx
79-
.table_mapping()
80-
.namespace(TableNamespace::by_component_definition_TODO())
81-
.id(&MODULE_VERSIONS_TABLE)?;
82-
if tx.writes().has_written_to(&module_versions_table_id) {
83-
let source = ModuleModel::new(tx)
84-
.get_source_from_db(module_metadata.id(), module_metadata.latest_version)
85-
.await?;
86-
return Ok(Arc::new(source));
87-
}
88-
89-
let key = (module_metadata.id(), module_metadata.latest_version);
70+
let key = (module_metadata.id(), module_metadata.source_package_id);
9071
let mut cache_tx = self.database.begin(Identity::system()).await?;
9172
let modules_storage = self.modules_storage.clone();
9273
let result = self

crates/database/src/writes.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ pub struct Writes {
6666
user_tx_size: TransactionWriteSize,
6767
// Size of writes to system tables
6868
system_tx_size: TransactionWriteSize,
69-
// When we write to module versions we cannot use the module cache.
70-
written_tables: BTreeSet<TabletIdAndTableNumber>,
7169
}
7270

7371
#[derive(Clone, Debug, Default, PartialEq)]
@@ -87,7 +85,6 @@ impl Writes {
8785
generated_ids: BTreeSet::new(),
8886
user_tx_size: TransactionWriteSize::default(),
8987
system_tx_size: TransactionWriteSize::default(),
90-
written_tables: BTreeSet::new(),
9188
}
9289
}
9390

@@ -96,10 +93,6 @@ impl Writes {
9693
self.updates.is_empty()
9794
}
9895

99-
pub fn has_written_to(&self, table_id: &TabletIdAndTableNumber) -> bool {
100-
self.written_tables.contains(table_id)
101-
}
102-
10396
pub fn update(
10497
&mut self,
10598
bootstrap_tables: BootstrapTableIds,
@@ -121,8 +114,6 @@ impl Writes {
121114
.map(|d| d.value().size())
122115
.unwrap_or(0);
123116

124-
self.written_tables.insert(*document_id.table());
125-
126117
let tx_size = if is_system_document {
127118
&mut self.system_tx_size
128119
} else {

crates/function_runner/src/module_cache.rs

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@ use isolate::environment::helpers::module_loader::get_module_and_prefetch;
1616
use model::{
1717
config::module_loader::ModuleLoader,
1818
modules::{
19-
module_versions::{
20-
FullModuleSource,
21-
ModuleVersion,
22-
},
19+
module_versions::FullModuleSource,
2320
types::ModuleMetadata,
2421
ModuleModel,
25-
MODULE_VERSIONS_TABLE,
2622
},
23+
source_packages::types::SourcePackageId,
2724
};
2825
use storage::Storage;
2926
use value::ResolvedDocumentId;
@@ -34,7 +31,7 @@ use crate::in_memory_indexes::TransactionIngredients;
3431
pub(crate) struct ModuleCacheKey {
3532
instance_name: String,
3633
module_id: ResolvedDocumentId,
37-
module_version: ModuleVersion,
34+
source_package_id: SourcePackageId,
3835
}
3936

4037
#[derive(Clone)]
@@ -70,27 +67,11 @@ impl<RT: Runtime> ModuleLoader<RT> for FunctionRunnerModuleLoader<RT> {
7067
// this module loader was created.
7168
assert_eq!(tx.begin_timestamp(), self.transaction_ingredients.ts);
7269

73-
let namespace = tx
74-
.table_mapping()
75-
.tablet_namespace(module_metadata.id().table().tablet_id)?;
76-
// If this transaction wrote to module_versions (true for REPLs), we cannot use
77-
// the cache, load the module directly.
78-
let module_versions_table_id = tx
79-
.table_mapping()
80-
.namespace(namespace)
81-
.id(&MODULE_VERSIONS_TABLE)?;
82-
if tx.writes().has_written_to(&module_versions_table_id) {
83-
let source = ModuleModel::new(tx)
84-
.get_source_from_db(module_metadata.id(), module_metadata.latest_version)
85-
.await?;
86-
return Ok(Arc::new(source));
87-
}
88-
8970
let instance_name = self.instance_name.clone();
9071
let key = ModuleCacheKey {
9172
instance_name: self.instance_name.clone(),
9273
module_id: module_metadata.id(),
93-
module_version: module_metadata.latest_version,
74+
source_package_id: module_metadata.source_package_id,
9475
};
9576
let mut transaction = self.transaction_ingredients.clone().try_into()?;
9677
let modules_storage = self.modules_storage.clone();
@@ -105,12 +86,12 @@ impl<RT: Runtime> ModuleLoader<RT> for FunctionRunnerModuleLoader<RT> {
10586
.await;
10687
modules
10788
.into_iter()
108-
.map(move |((module_id, module_version), source)| {
89+
.map(move |((module_id, source_package_id), source)| {
10990
(
11091
ModuleCacheKey {
11192
instance_name: instance_name.clone(),
11293
module_id,
113-
module_version,
94+
source_package_id,
11495
},
11596
source,
11697
)

crates/isolate/src/environment/helpers/module_loader.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@ use database::Transaction;
1414
use deno_core::ModuleSpecifier;
1515
use model::{
1616
modules::{
17-
module_versions::{
18-
FullModuleSource,
19-
ModuleVersion,
20-
},
17+
module_versions::FullModuleSource,
2118
types::ModuleMetadata,
2219
ModuleModel,
2320
},
@@ -45,7 +42,7 @@ pub async fn get_module_and_prefetch<RT: Runtime>(
4542
tx: &mut Transaction<RT>,
4643
modules_storage: Arc<dyn Storage>,
4744
module_metadata: ParsedDocument<ModuleMetadata>,
48-
) -> HashMap<(ResolvedDocumentId, ModuleVersion), anyhow::Result<FullModuleSource>> {
45+
) -> HashMap<(ResolvedDocumentId, SourcePackageId), anyhow::Result<FullModuleSource>> {
4946
let all_source_result = if *READ_MODULES_FROM_SOURCE_PACKAGE {
5047
let _timer = module_load_timer("package");
5148
download_module_source_from_package(
@@ -63,7 +60,7 @@ pub async fn get_module_and_prefetch<RT: Runtime>(
6360
.map(|source| {
6461
let mut result = HashMap::new();
6562
result.insert(
66-
(module_metadata.id(), module_metadata.latest_version),
63+
(module_metadata.id(), module_metadata.source_package_id),
6764
source,
6865
);
6966
result
@@ -73,7 +70,7 @@ pub async fn get_module_and_prefetch<RT: Runtime>(
7370
Err(e) => {
7471
let mut result = HashMap::new();
7572
result.insert(
76-
(module_metadata.id(), module_metadata.latest_version),
73+
(module_metadata.id(), module_metadata.source_package_id),
7774
Err(e),
7875
);
7976
result
@@ -91,7 +88,7 @@ async fn download_module_source_from_package<RT: Runtime>(
9188
modules_storage: Arc<dyn Storage>,
9289
modules_tablet: TabletId,
9390
source_package_id: SourcePackageId,
94-
) -> anyhow::Result<HashMap<(ResolvedDocumentId, ModuleVersion), FullModuleSource>> {
91+
) -> anyhow::Result<HashMap<(ResolvedDocumentId, SourcePackageId), FullModuleSource>> {
9592
let mut result = HashMap::new();
9693
let source_package = SourcePackageModel::new(tx).get(source_package_id).await?;
9794
let mut package = download_package(
@@ -119,7 +116,7 @@ async fn download_module_source_from_package<RT: Runtime>(
119116
},
120117
Some(source) => {
121118
result.insert(
122-
(module_metadata.id(), module_metadata.latest_version),
119+
(module_metadata.id(), module_metadata.source_package_id),
123120
FullModuleSource {
124121
source: source.source,
125122
source_map: source.source_map,

crates/model/src/modules/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ impl<'a, RT: Runtime> ModuleModel<'a, RT> {
311311
pub async fn get_version(
312312
&mut self,
313313
module_id: ResolvedDocumentId,
314-
version: ModuleVersion,
314+
version: Option<ModuleVersion>,
315315
) -> anyhow::Result<Option<ParsedDocument<ModuleVersionMetadata>>> {
316316
let timer = get_module_version_timer();
317317
let module_id_value: ConvexValue = module_id.into();
@@ -335,7 +335,7 @@ impl<'a, RT: Runtime> ModuleModel<'a, RT> {
335335
.map(TryFrom::try_from)
336336
.transpose()?;
337337
if let Some(module_version) = &module_version {
338-
anyhow::ensure!(module_version.version == Some(version));
338+
anyhow::ensure!(module_version.version == version);
339339
}
340340
timer.finish();
341341
Ok(module_version)
@@ -345,13 +345,13 @@ impl<'a, RT: Runtime> ModuleModel<'a, RT> {
345345
pub async fn get_source_from_db(
346346
&mut self,
347347
module_id: ResolvedDocumentId,
348-
version: ModuleVersion,
348+
version: Option<ModuleVersion>,
349349
) -> anyhow::Result<FullModuleSource> {
350350
let module_version = self
351351
.get_version(module_id, version)
352352
.await?
353353
.context(format!(
354-
"Dangling module version reference: {module_id}@{version}"
354+
"Dangling module version reference: {module_id}@{version:?}"
355355
))?
356356
.into_value();
357357
Ok(FullModuleSource {
@@ -426,7 +426,7 @@ impl<'a, RT: Runtime> ModuleModel<'a, RT> {
426426
analyze_result: Option<AnalyzedModule>,
427427
environment: ModuleEnvironment,
428428
sha256: Sha256Digest,
429-
) -> anyhow::Result<(ResolvedDocumentId, ModuleVersion)> {
429+
) -> anyhow::Result<(ResolvedDocumentId, Option<ModuleVersion>)> {
430430
let (module_id, version) = match self.module_metadata(path.clone()).await? {
431431
Some(module_metadata) => {
432432
let previous_version = module_metadata.latest_version;
@@ -437,7 +437,7 @@ impl<'a, RT: Runtime> ModuleModel<'a, RT> {
437437
.await?
438438
.map(|version| version.id());
439439

440-
let latest_version = previous_version + 1;
440+
let latest_version = previous_version.map(|v| v + 1);
441441
let new_metadata = ModuleMetadata {
442442
path: path.module_path,
443443
latest_version,
@@ -459,7 +459,7 @@ impl<'a, RT: Runtime> ModuleModel<'a, RT> {
459459
(module_metadata.id(), latest_version)
460460
},
461461
None => {
462-
let version = 0;
462+
let version = Some(0);
463463
let new_metadata = ModuleMetadata {
464464
path: path.module_path,
465465
latest_version: version,
@@ -481,7 +481,7 @@ impl<'a, RT: Runtime> ModuleModel<'a, RT> {
481481
async fn put_module_source_into_db(
482482
&mut self,
483483
module_id: ResolvedDocumentId,
484-
version: ModuleVersion,
484+
version: Option<ModuleVersion>,
485485
source: ModuleSource,
486486
source_map: Option<SourceMap>,
487487
component: ComponentId,
@@ -490,7 +490,7 @@ impl<'a, RT: Runtime> ModuleModel<'a, RT> {
490490
module_id: module_id.into(),
491491
source,
492492
source_map,
493-
version: Some(version),
493+
version,
494494
}.try_into()
495495
.map_err(|e: anyhow::Error| e.map_error_metadata(|em| {
496496
if em.short_msg == VALUE_TOO_LARGE_SHORT_MSG {

crates/model/src/modules/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub struct ModuleMetadata {
2727
/// Path stored as a "path" field.
2828
pub path: CanonicalizedModulePath,
2929
/// What is the latest version of the module?
30-
pub latest_version: ModuleVersion,
30+
pub latest_version: Option<ModuleVersion>,
3131

3232
pub source_package_id: SourcePackageId,
3333
pub environment: ModuleEnvironment,
@@ -40,7 +40,7 @@ pub struct ModuleMetadata {
4040
#[serde(rename_all = "camelCase")]
4141
pub struct SerializedModuleMetadata {
4242
pub path: String,
43-
pub latest_version: ModuleVersion,
43+
pub latest_version: Option<ModuleVersion>,
4444
pub deleted: Option<bool>,
4545
pub source_package_id: String,
4646
pub environment: String,

crates/model/src/source_packages/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl TryFrom<PackageSize> for ConvexObject {
128128
}
129129

130130
#[cfg_attr(any(test, feature = "testing"), derive(proptest_derive::Arbitrary))]
131-
#[derive(Debug, Clone, PartialEq, Eq, Copy, PartialOrd, Ord)]
131+
#[derive(Debug, Clone, PartialEq, Eq, Copy, PartialOrd, Ord, Hash)]
132132
pub struct SourcePackageId(DeveloperDocumentId);
133133

134134
impl HeapSize for SourcePackageId {

0 commit comments

Comments
 (0)