1919
2020import java .util .ArrayList ;
2121import java .util .List ;
22+ import java .util .Map ;
2223import java .util .Set ;
2324import java .util .concurrent .ConcurrentHashMap ;
25+ import java .util .concurrent .atomic .AtomicBoolean ;
2426import java .util .function .Consumer ;
2527
2628import org .apache .hugegraph .HugeGraphParams ;
4345
4446public class CachedSchemaTransactionV2 extends SchemaTransactionV2 {
4547
48+ private static final String ID_CACHE_PREFIX = "schema-id" ;
49+ private static final String NAME_CACHE_PREFIX = "schema-name" ;
50+
51+ // MetaDriver doesn't expose unlisten, register the PD listener once.
52+ private static final AtomicBoolean metaEventListenerRegistered =
53+ new AtomicBoolean (false );
54+
4655 private final Cache <Id , Object > idCache ;
4756 private final Cache <Id , Object > nameCache ;
4857
@@ -58,8 +67,8 @@ public CachedSchemaTransactionV2(MetaDriver metaDriver,
5867
5968 final long capacity = graphParams .configuration ()
6069 .get (CoreOptions .SCHEMA_CACHE_CAPACITY );
61- this .idCache = this .cache ("schema-id" , capacity );
62- this .nameCache = this .cache ("schema-name" , capacity );
70+ this .idCache = this .cache (ID_CACHE_PREFIX , capacity );
71+ this .nameCache = this .cache (NAME_CACHE_PREFIX , capacity );
6372
6473 SchemaCaches <SchemaElement > attachment = this .idCache .attachment ();
6574 if (attachment == null ) {
@@ -86,11 +95,36 @@ public void close() {
8695 }
8796
8897 private Cache <Id , Object > cache (String prefix , long capacity ) {
89- final String name = prefix + "-" + this .graph ().spaceGraphName ();
98+ final String name = cacheName ( prefix , this .graph ().spaceGraphName () );
9099 // NOTE: must disable schema cache-expire due to getAllSchema()
91100 return CacheManager .instance ().cache (name , capacity );
92101 }
93102
103+ private static String cacheName (String prefix , String spaceGraphName ) {
104+ return prefix + "-" + spaceGraphName ;
105+ }
106+
107+ private static void clearSchemaCache (String spaceGraphName ) {
108+ Map <String , Cache <Id , Object >> caches = CacheManager .instance ().caches ();
109+
110+ Cache <Id , Object > idCache = caches .get (cacheName (ID_CACHE_PREFIX ,
111+ spaceGraphName ));
112+ if (idCache != null ) {
113+ idCache .clear ();
114+
115+ SchemaCaches <?> arrayCaches = idCache .attachment ();
116+ if (arrayCaches != null ) {
117+ arrayCaches .clear ();
118+ }
119+ }
120+
121+ Cache <Id , Object > nameCache = caches .get (cacheName (NAME_CACHE_PREFIX ,
122+ spaceGraphName ));
123+ if (nameCache != null ) {
124+ nameCache .clear ();
125+ }
126+ }
127+
94128 private void listenChanges () {
95129 // Listen store event: "store.init", "store.clear", ...
96130 Set <String > storeEvents = ImmutableSet .of (Events .STORE_INIT ,
@@ -142,15 +176,44 @@ private void listenChanges() {
142176 return false ;
143177 };
144178 EventHub schemaEventHub = this .graphParams ().schemaEventHub ();
145- if (!schemaEventHub .containsListener (Events .CACHE )) {
146- schemaEventHub .listen (Events .CACHE , this .cacheEventListener );
179+ schemaEventHub .listen (Events .CACHE , this .cacheEventListener );
180+
181+ listenSchemaCacheClear ();
182+ }
183+
184+ private static void listenSchemaCacheClear () {
185+ if (!metaEventListenerRegistered .compareAndSet (false , true )) {
186+ return ;
187+ }
188+
189+ try {
190+ MetaDriver metaDriver = MetaManager .instance ().metaDriver ();
191+ MetaManager .instance ().listenSchemaCacheClear (response -> {
192+ List <String > graphNames =
193+ metaDriver .extractValuesFromResponse (response );
194+ if (graphNames == null ) {
195+ return ;
196+ }
197+ for (String graphName : graphNames ) {
198+ LOG .debug ("Graph {} clear schema cache on meta event" ,
199+ graphName );
200+ clearSchemaCache (graphName );
201+ }
202+ });
203+ } catch (RuntimeException e ) {
204+ metaEventListenerRegistered .set (false );
205+ throw e ;
147206 }
148207 }
149208
150209 public void clearCache (boolean notify ) {
151210 this .idCache .clear ();
152211 this .nameCache .clear ();
153212 this .arrayCaches .clear ();
213+
214+ if (notify ) {
215+ this .notifySchemaCacheClear ();
216+ }
154217 }
155218
156219 private void resetCachedAllIfReachedCapacity () {
@@ -202,6 +265,7 @@ protected void updateSchema(SchemaElement schema,
202265 super .updateSchema (schema , updateCallback );
203266
204267 this .updateCache (schema );
268+ this .notifySchemaCacheClear ();
205269 }
206270
207271 @ Override
@@ -210,11 +274,7 @@ protected void addSchema(SchemaElement schema) {
210274
211275 this .updateCache (schema );
212276
213- if (!this .graph ().option (CoreOptions .TASK_SYNC_DELETION )) {
214- MetaManager .instance ()
215- .notifySchemaCacheClear (this .graph ().graphSpace (),
216- this .graph ().name ());
217- }
277+ this .notifySchemaCacheClear ();
218278 }
219279
220280 private void updateCache (SchemaElement schema ) {
@@ -238,6 +298,10 @@ public void removeSchema(SchemaElement schema) {
238298
239299 this .invalidateCache (schema .type (), schema .id ());
240300
301+ this .notifySchemaCacheClear ();
302+ }
303+
304+ private void notifySchemaCacheClear () {
241305 if (!this .graph ().option (CoreOptions .TASK_SYNC_DELETION )) {
242306 MetaManager .instance ()
243307 .notifySchemaCacheClear (this .graph ().graphSpace (),
0 commit comments