haohao0103 commented on issue #2618:
URL:
https://github.com/apache/incubator-hugegraph/issues/2618#issuecomment-2270324016
> 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
[[1]](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedGraphTransaction.java)[[2]](https://github.com/apache/incubator-hugegraph/blob/master/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/cache/CachedSchemaTransaction.java).
>
> _To continue talking to [Dosu](https://dosu.dev), mention @dosu._
@dosu // Check if the storeEventListener is already registered
if (!this.store().provider().containsListener(this.storeEventListener)) {
this.store().provider().listen(this.storeEventListener);
}
this logic cannot avoid duplicate registration of storeEventListener,
--
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]