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

   <!-- Answer -->
   To resolve the issue of `StoreEventListener` being registered and monitored 
repeatedly in `CachedSystemTransactionV2` and `CachedGraphTransaction`, you 
need to ensure that the listeners are not registered multiple times. This can 
be achieved by checking if the listeners are already registered before adding 
them. Here is how you can modify the `listenChanges` method to include this 
check:
   
   ```java
   private void listenChanges() {
       // 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;
       };
   
       // Check if the storeEventListener is already registered
       if (!this.store().provider().containsListener(this.storeEventListener)) {
           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();
       // Check if the cacheEventListener is already registered
       if (!graphEventHub.containsListener(Events.CACHE)) {
           graphEventHub.listen(Events.CACHE, this.cacheEventListener);
       }
   }
   ```
   
   Additionally, you should implement an `unlistenChanges` method to ensure 
that the listeners are properly unregistered when they are no longer needed, 
similar to the approach used in `CachedSchemaTransaction`:
   
   ```java
   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);
   }
   ```
   
   By adding these checks and ensuring proper unregistration, you ensure that 
the listeners are only registered once, preventing the issue of them being 
registered and monitored repeatedly 
<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><sup>[[2]](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransaction.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