Skip to content

Commit 7164866

Browse files
authored
Add config option for cache stores (#5716)
1 parent 4ff59df commit 7164866

File tree

8 files changed

+55
-17
lines changed

8 files changed

+55
-17
lines changed

chain/substreams/src/trigger.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,11 @@ where
225225
logger,
226226
);
227227

228-
state.entity_cache.set(key, entity)?;
228+
state.entity_cache.set(
229+
key,
230+
entity,
231+
Some(&mut state.write_capacity_remaining),
232+
)?;
229233
}
230234
ParsedChanges::Delete(entity_key) => {
231235
let entity_type = entity_key.entity_type.cheap_clone();

core/src/subgraph/runner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1646,7 +1646,7 @@ async fn update_proof_of_indexing(
16461646
data.push((entity_cache.schema.poi_block_time(), block_time));
16471647
}
16481648
let poi = entity_cache.make_entity(data)?;
1649-
entity_cache.set(key, poi)
1649+
entity_cache.set(key, poi, None)
16501650
}
16511651

16521652
let _section_guard = stopwatch.start_section("update_proof_of_indexing");

graph/src/components/store/entity_cache.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::cheap_clone::CheapClone;
88
use crate::components::store::write::EntityModification;
99
use crate::components::store::{self as s, Entity, EntityOperation};
1010
use crate::data::store::{EntityValidationError, Id, IdType, IntoEntityIterator};
11-
use crate::prelude::ENV_VARS;
11+
use crate::prelude::{CacheWeight, ENV_VARS};
1212
use crate::schema::{EntityKey, InputSchema};
1313
use crate::util::intern::Error as InternError;
1414
use crate::util::lfu_cache::{EvictStats, LfuCache};
@@ -349,10 +349,28 @@ impl EntityCache {
349349
/// with existing data. The entity will be validated against the
350350
/// subgraph schema, and any errors will result in an `Err` being
351351
/// returned.
352-
pub fn set(&mut self, key: EntityKey, entity: Entity) -> Result<(), anyhow::Error> {
352+
pub fn set(
353+
&mut self,
354+
key: EntityKey,
355+
entity: Entity,
356+
write_capacity_remaining: Option<&mut usize>,
357+
) -> Result<(), anyhow::Error> {
353358
// check the validate for derived fields
354359
let is_valid = entity.validate(&key).is_ok();
355360

361+
if let Some(write_capacity_remaining) = write_capacity_remaining {
362+
let weight = entity.weight();
363+
364+
if !self.current.contains_key(&key) && weight > *write_capacity_remaining {
365+
return Err(anyhow!(
366+
"exceeded block write limit when writing entity `{}`",
367+
key.entity_id,
368+
));
369+
}
370+
371+
*write_capacity_remaining -= weight;
372+
}
373+
356374
self.entity_op(key.clone(), EntityOp::Update(entity));
357375

358376
// The updates we were given are not valid by themselves; force a

graph/src/components/subgraph/instance.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pub struct BlockState {
8181
in_handler: bool,
8282

8383
pub metrics: BlockStateMetrics,
84+
85+
pub write_capacity_remaining: usize,
8486
}
8587

8688
impl BlockState {
@@ -94,6 +96,7 @@ impl BlockState {
9496
processed_data_sources: Vec::new(),
9597
in_handler: false,
9698
metrics: BlockStateMetrics::new(),
99+
write_capacity_remaining: ENV_VARS.block_write_capacity,
97100
}
98101
}
99102
}
@@ -111,6 +114,7 @@ impl BlockState {
111114
processed_data_sources,
112115
in_handler,
113116
metrics,
117+
write_capacity_remaining,
114118
} = self;
115119

116120
match in_handler {
@@ -121,7 +125,9 @@ impl BlockState {
121125
entity_cache.extend(other.entity_cache);
122126
processed_data_sources.extend(other.processed_data_sources);
123127
persisted_data_sources.extend(other.persisted_data_sources);
124-
metrics.extend(other.metrics)
128+
metrics.extend(other.metrics);
129+
*write_capacity_remaining =
130+
write_capacity_remaining.saturating_sub(other.write_capacity_remaining);
125131
}
126132

127133
pub fn has_errors(&self) -> bool {

graph/src/env/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ pub struct EnvVars {
238238
///
239239
/// Defaults to an empty list, which means that this feature is enabled for all chains;
240240
pub firehose_disable_extended_blocks_for_chains: Vec<String>,
241+
242+
pub block_write_capacity: usize,
241243
}
242244

243245
impl EnvVars {
@@ -327,6 +329,7 @@ impl EnvVars {
327329
Self::firehose_disable_extended_blocks_for_chains(
328330
inner.firehose_disable_extended_blocks_for_chains,
329331
),
332+
block_write_capacity: inner.block_write_capacity.0,
330333
})
331334
}
332335

@@ -488,6 +491,8 @@ struct Inner {
488491
graphman_server_auth_token: Option<String>,
489492
#[envconfig(from = "GRAPH_NODE_FIREHOSE_DISABLE_EXTENDED_BLOCKS_FOR_CHAINS")]
490493
firehose_disable_extended_blocks_for_chains: Option<String>,
494+
#[envconfig(from = "GRAPH_NODE_BLOCK_WRITE_CAPACITY", default = "4_000_000_000")]
495+
block_write_capacity: NoUnderscores<usize>,
491496
}
492497

493498
#[derive(Clone, Debug)]

runtime/wasm/src/host_exports.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,9 @@ impl HostExports {
350350

351351
state.metrics.track_entity_write(&entity_type, &entity);
352352

353-
state.entity_cache.set(key, entity)?;
353+
state
354+
.entity_cache
355+
.set(key, entity, Some(&mut state.write_capacity_remaining))?;
354356

355357
Ok(())
356358
}

store/postgres/src/deployment_store.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -874,8 +874,7 @@ impl DeploymentStore {
874874
}
875875
}
876876

877-
/// Methods that back the trait `graph::components::Store`, but have small
878-
/// variations in their signatures
877+
/// Methods that back the trait `WritableStore`, but have small variations in their signatures
879878
impl DeploymentStore {
880879
pub(crate) async fn block_ptr(&self, site: Arc<Site>) -> Result<Option<BlockPtr>, StoreError> {
881880
let site = site.cheap_clone();

store/test-store/tests/graph/entity_cache.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,14 @@ fn insert_modifications() {
209209

210210
let mogwai_data = entity! { SCHEMA => id: "mogwai", name: "Mogwai" };
211211
let mogwai_key = make_band_key("mogwai");
212-
cache.set(mogwai_key.clone(), mogwai_data.clone()).unwrap();
212+
cache
213+
.set(mogwai_key.clone(), mogwai_data.clone(), None)
214+
.unwrap();
213215

214216
let sigurros_data = entity! { SCHEMA => id: "sigurros", name: "Sigur Ros" };
215217
let sigurros_key = make_band_key("sigurros");
216218
cache
217-
.set(sigurros_key.clone(), sigurros_data.clone())
219+
.set(sigurros_key.clone(), sigurros_data.clone(), None)
218220
.unwrap();
219221

220222
let result = cache.as_modifications(0);
@@ -253,12 +255,14 @@ fn overwrite_modifications() {
253255

254256
let mogwai_data = entity! { SCHEMA => id: "mogwai", name: "Mogwai", founded: 1995 };
255257
let mogwai_key = make_band_key("mogwai");
256-
cache.set(mogwai_key.clone(), mogwai_data.clone()).unwrap();
258+
cache
259+
.set(mogwai_key.clone(), mogwai_data.clone(), None)
260+
.unwrap();
257261

258262
let sigurros_data = entity! { SCHEMA => id: "sigurros", name: "Sigur Ros", founded: 1994 };
259263
let sigurros_key = make_band_key("sigurros");
260264
cache
261-
.set(sigurros_key.clone(), sigurros_data.clone())
265+
.set(sigurros_key.clone(), sigurros_data.clone(), None)
262266
.unwrap();
263267

264268
let result = cache.as_modifications(0);
@@ -289,12 +293,12 @@ fn consecutive_modifications() {
289293
let update_data =
290294
entity! { SCHEMA => id: "mogwai", founded: 1995, label: "Rock Action Records" };
291295
let update_key = make_band_key("mogwai");
292-
cache.set(update_key, update_data).unwrap();
296+
cache.set(update_key, update_data, None).unwrap();
293297

294298
// Then, just reset the "label".
295299
let update_data = entity! { SCHEMA => id: "mogwai", label: Value::Null };
296300
let update_key = make_band_key("mogwai");
297-
cache.set(update_key.clone(), update_data).unwrap();
301+
cache.set(update_key.clone(), update_data, None).unwrap();
298302

299303
// We expect a single overwrite modification for the above that leaves "id"
300304
// and "name" untouched, sets "founded" and removes the "label" field.
@@ -715,7 +719,7 @@ fn scoped_get() {
715719
let account5 = ACCOUNT_TYPE.parse_id("5").unwrap();
716720
let wallet5 = create_wallet_entity("5", &account5, 100);
717721
let key5 = WALLET_TYPE.parse_key("5").unwrap();
718-
cache.set(key5.clone(), wallet5.clone()).unwrap();
722+
cache.set(key5.clone(), wallet5.clone(), None).unwrap();
719723

720724
// For the new entity, we can retrieve it with either scope
721725
let act5 = cache.get(&key5, GetScope::InBlock).unwrap();
@@ -736,7 +740,7 @@ fn scoped_get() {
736740
// But if it gets updated, it becomes visible with either scope
737741
let mut wallet1 = wallet1;
738742
wallet1.set("balance", 70).unwrap();
739-
cache.set(key1.clone(), wallet1.clone()).unwrap();
743+
cache.set(key1.clone(), wallet1.clone(), None).unwrap();
740744
let act1 = cache.get(&key1, GetScope::InBlock).unwrap();
741745
assert_eq!(Some(&wallet1), act1.as_ref().map(|e| e.as_ref()));
742746
let act1 = cache.get(&key1, GetScope::Store).unwrap();
@@ -783,6 +787,6 @@ fn no_interface_mods() {
783787

784788
let entity = entity! { LOAD_RELATED_SUBGRAPH => id: "1", balance: 100 };
785789

786-
cache.set(key, entity).unwrap_err();
790+
cache.set(key, entity, None).unwrap_err();
787791
})
788792
}

0 commit comments

Comments
 (0)