dosubot[bot] commented on issue #2618:
URL: 
https://github.com/apache/incubator-hugegraph/issues/2618#issuecomment-2270327041

   <!-- Answer -->
   To ensure that `storeEventListener` is not registered multiple times in 
`CachedSystemTransactionV2` and `CachedGraphTransaction`, you can use a 
`ThreadLocal` variable to keep track of whether the listener has already been 
registered for the current thread. Here is an example of how you can modify the 
`listenChanges` method to achieve this:
   
   ```java
   public final class CachedGraphTransaction extends GraphTransaction {
   
       private static final ThreadLocal<Boolean> listenerRegistered = 
ThreadLocal.withInitial(() -> false);
   
       private void listenChanges() {
           if (listenerRegistered.get()) {
               return;
           }
   
           // Listen store event: "store.init", "store.clear", ...
           Set<String> storeEvents = ImmutableSet.of(Events.STORE_INIT,
                                                     Events.STORE_CLEAR,
                                                     Events.STORE_TRUNCATE);
           this.storeEventListener = event -> {
               if (storeEvents.contains(event.name())) {
                   LOG.debug("Graph {} clear graph cache on event '{}'",
                             this.graph(), event.name());
                   this.clearCache(null, true);
                   return true;
               }
               return false;
           };
           this.store().provider().listen(this.storeEventListener);
   
           // Listen cache event: "cache"(invalid cache item)
           this.cacheEventListener = event -> {
               LOG.debug("Graph {} received graph cache event: {}",
                         this.graph(), event);
               Object[] args = event.args();
               E.checkArgument(args.length > 0 && args[0] instanceof String,
                               "Expect event action argument");
               if (Cache.ACTION_INVALID.equals(args[0])) {
                   event.checkArgs(String.class, HugeType.class, Object.class);
                   HugeType type = (HugeType) args[1];
                   if (type.isVertex()) {
                       // Invalidate vertex cache
                       Object arg2 = args[2];
                       if (arg2 instanceof Id) {
                           Id id = (Id) arg2;
                           this.verticesCache.invalidate(id);
                       } else if (arg2 != null && arg2.getClass().isArray()) {
                           int size = Array.getLength(arg2);
                           for (int i = 0; i < size; i++) {
                               Object id = Array.get(arg2, i);
                               E.checkArgument(id instanceof Id,
                                               "Expect instance of Id in array, 
" +
                                               "but got '%s'", id.getClass());
                               this.verticesCache.invalidate((Id) id);
                           }
                       } else {
                           E.checkArgument(false,
                                           "Expect Id or Id[], but got: %s",
                                           arg2);
                       }
                   } else if (type.isEdge()) {
                       /*
                        * Invalidate edge cache via clear instead of invalidate
                        * because of the cacheKey is QueryId not EdgeId
                        */
                       // this.edgesCache.invalidate(id);
                       this.edgesCache.clear();
                   }
                   return true;
               } else if (Cache.ACTION_CLEAR.equals(args[0])) {
                   event.checkArgs(String.class, HugeType.class);
                   HugeType type = (HugeType) args[1];
                   this.clearCache(type, false);
                   return true;
               }
               return false;
           };
           EventHub graphEventHub = this.params().graphEventHub();
           if (!graphEventHub.containsListener(Events.CACHE)) {
               graphEventHub.listen(Events.CACHE, this.cacheEventListener);
           }
   
           listenerRegistered.set(true);
       }
   
       private void unlistenChanges() {
           // Unlisten store event
           this.store().provider().unlisten(this.storeEventListener);
   
           // Unlisten cache event
           EventHub graphEventHub = this.params().graphEventHub();
           graphEventHub.unlisten(Events.CACHE, this.cacheEventListener);
   
           listenerRegistered.set(false);
       }
   
       // Other methods...
   }
   ```
   
   This code uses a `ThreadLocal` variable `listenerRegistered` to keep track 
of whether the listeners have been registered for the current thread. The 
`listenChanges` method checks this variable before registering the listeners, 
and the `unlistenChanges` method resets it when the listeners are unregistered 
<sup>[[1]](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedGraphTransaction.java)</sup>.
   
   
   <!-- Dosu Comment Footer -->
   *To continue talking to [Dosu](https://dosu.dev), mention @dosu.*
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to