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]