@@ -4,7 +4,11 @@ use diesel::{
4
4
sql_types:: Text ,
5
5
types:: { FromSql , ToSql } ,
6
6
} ;
7
- use std:: { collections:: BTreeMap , collections:: HashMap , sync:: Arc } ;
7
+ use std:: {
8
+ collections:: BTreeMap ,
9
+ collections:: HashMap ,
10
+ sync:: { Arc , Mutex } ,
11
+ } ;
8
12
use std:: { fmt, io:: Write } ;
9
13
use std:: { iter:: FromIterator , time:: Duration } ;
10
14
@@ -256,6 +260,7 @@ pub struct SubgraphStoreInner {
256
260
sites : TimedCache < DeploymentHash , Site > ,
257
261
placer : Arc < dyn DeploymentPlacer + Send + Sync + ' static > ,
258
262
sender : Arc < NotificationSender > ,
263
+ writables : Mutex < HashMap < DeploymentId , Arc < WritableStore > > > ,
259
264
}
260
265
261
266
impl SubgraphStoreInner {
@@ -309,6 +314,7 @@ impl SubgraphStoreInner {
309
314
sites,
310
315
placer,
311
316
sender,
317
+ writables : Mutex :: new ( HashMap :: new ( ) ) ,
312
318
}
313
319
}
314
320
@@ -1045,19 +1051,28 @@ impl SubgraphStoreTrait for SubgraphStore {
1045
1051
logger : Logger ,
1046
1052
deployment : graph:: components:: store:: DeploymentId ,
1047
1053
) -> Result < Arc < dyn store:: WritableStore > , StoreError > {
1054
+ let deployment = deployment. into ( ) ;
1055
+ // We cache writables to make sure calls to this method are
1056
+ // idempotent and there is ever only one `WritableStore` for any
1057
+ // deployment
1058
+ if let Some ( writable) = self . writables . lock ( ) . unwrap ( ) . get ( & deployment) {
1059
+ return Ok ( writable. cheap_clone ( ) ) ;
1060
+ }
1061
+
1048
1062
// Ideally the lower level functions would be asyncified.
1049
1063
let this = self . clone ( ) ;
1050
1064
let site = graph:: spawn_blocking_allow_panic ( move || -> Result < _ , StoreError > {
1051
- this. find_site ( deployment. into ( ) )
1065
+ this. find_site ( deployment)
1052
1066
} )
1053
1067
. await
1054
1068
. unwrap ( ) ?; // Propagate panics, there shouldn't be any.
1055
1069
1056
- Ok ( Arc :: new ( WritableStore :: new (
1057
- self . as_ref ( ) . clone ( ) ,
1058
- logger,
1059
- site,
1060
- ) ?) )
1070
+ let writable = Arc :: new ( WritableStore :: new ( self . as_ref ( ) . clone ( ) , logger, site) ?) ;
1071
+ self . writables
1072
+ . lock ( )
1073
+ . unwrap ( )
1074
+ . insert ( deployment, writable. cheap_clone ( ) ) ;
1075
+ Ok ( writable)
1061
1076
}
1062
1077
1063
1078
fn writable_for_network_indexer (
0 commit comments