Custom MutationListener on Transaction

Hello everyone, I'm a beginner regarding tinkerpop and i'm trying to fire my custom listener after a transaction is done. I have registered an EventStrategy on my JanusGraph
graph.traversal().withStrategies(EventStrategy.build().eventQueue(new CustomTransactionnalEventQueue(graph)).addListener(new CustomListener(graph.traversal())).create())
graph.traversal().withStrategies(EventStrategy.build().eventQueue(new CustomTransactionnalEventQueue(graph)).addListener(new CustomListener(graph.traversal())).create())
The Custom transactionnal Event Queue is just a copy of the one in the EventStrategy class with logs at every step to help me find where the problem is . Now the problem : I have noticed that my transaction are never mark as committed. i tried a simple g.addV() :
gremlin> g.addV("aeaeazezeezee")
==>v[368652472]
gremlin> g.addV("aeaeazezeezee")
==>v[368652472]
and tried using
g.tx().commit()
g.tx().commit()
I see in my logs that the event are catched and added to the eventQueue but my listeners is never used on them since the status of my transaction is never marked as commited. I hope I'm clear in my explanation. I can provide more information/code if needed Regards
13 Replies
spmallette
spmallette2y ago
you dont have a single continuous Gremlin Console session there so it's a little hard to be sure what's happening. could you perhaps share a full console session that demonstrates the setup of g and the order in which your example works?
Napsetern
NapseternOP2y ago
Sure, so I have a JanusGraph where I define in the groovy script g with the EventStrategy and my Custom Listener
globals << [g : graph.traversal().withStrategies(EventStrategy.build().eventQueue(new CustomTransactionnalEventQueue(graph)).addListener(new CustomListener(graph.traversal())).create())]
globals << [g : graph.traversal().withStrategies(EventStrategy.build().eventQueue(new CustomTransactionnalEventQueue(graph)).addListener(new CustomListener(graph.traversal())).create())]
I then start it and see in my logs that both my transactionnal queue and listener are created Then I launch gremlin
./bin/gremlin.sh start
./bin/gremlin.sh start
gremlin> :remote connect tinkerpop.server conf/remote.yaml
==>Configured localhost/127.0.0.1:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182] - type ':remote console' to return to local mode
gremlin>
gremlin> :remote connect tinkerpop.server conf/remote.yaml
==>Configured localhost/127.0.0.1:8182
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182] - type ':remote console' to return to local mode
gremlin>
I add a vertex
gremlin> g.addV("test")
==>v[245764288]
gremlin> g.addV("test")
==>v[245764288]
I see that my EventQueue size increased but my listener is not triggered. Since It's a transactionnal queue I try to use g.tx() :
gremlin> g.tx().open()
==>null
gremlin> g.addV("test2")
==>v[614404184]
gremlin> g.tx().commit()
==>null
gremlin> g.tx().close()
==>null
gremlin> g.tx().open()
==>null
gremlin> g.addV("test2")
==>v[614404184]
gremlin> g.tx().commit()
==>null
gremlin> g.tx().close()
==>null
but I see in my logs the same output as a lone g.addV(), my EventQueue gets populated with the event but my event queue is never fired. Basically in the TransactionnalEventQueue code below from EventStrategy class I have the feeling that I never go into the else part.
public TransactionalEventQueue(final Graph graph) {
if (!graph.features().graph().supportsTransactions()) {
throw new IllegalStateException(String.format("%s requires the graph to support transactions", EventStrategy.class.getName()));
} else {
graph.tx().addTransactionListener((status) -> {
if (status == Status.COMMIT) {
this.fireEventQueue();
} else {
if (status != Status.ROLLBACK) {
throw new RuntimeException(String.format("The %s is not aware of this status: %s", EventQueue.class.getName(), status));
}

this.resetEventQueue();
}

});
}
}
public TransactionalEventQueue(final Graph graph) {
if (!graph.features().graph().supportsTransactions()) {
throw new IllegalStateException(String.format("%s requires the graph to support transactions", EventStrategy.class.getName()));
} else {
graph.tx().addTransactionListener((status) -> {
if (status == Status.COMMIT) {
this.fireEventQueue();
} else {
if (status != Status.ROLLBACK) {
throw new RuntimeException(String.format("The %s is not aware of this status: %s", EventQueue.class.getName(), status));
}

this.resetEventQueue();
}

});
}
}
spmallette
spmallette2y ago
Does this work if you take Gremlin Server out of the picture and just execute all the same directly in Gremlin Console or in a simple embedded application?
Napsetern
NapseternOP2y ago
I have tested it with a simple Java App , I tried commit, close and it's no different that just doing a simple addV(), event are catched and added to the event queue but listener is never fired on those event.
spmallette
spmallette2y ago
do the EventStrategy tests run for @janusgraph ?
Napsetern
NapseternOP2y ago
I had no problem with a non TransactionnalEventQueue (I think it's called DefaultEventQueue) my event are caught and my listener is triggered
spmallette
spmallette2y ago
that was a question for JanusGraph contributors. i'm wondering if the TinkerPop test suite that checks that functionality is running.
Dendriform
Dendriform2y ago
There is a JanusGraph Discord server as well.
Bo
Bo2y ago
EventStrategyProcessTest::shouldResetAfterRollback is disabled for JanusGraph. Others are enabled. @Napsetern Can you try this: after a transaction is completed, manually call
graph.tx().addTransactionListener(listener);
graph.tx().addTransactionListener(listener);
explicitly if you want to reuse this listener. See https://docs.janusgraph.org/changelog/#breaking-change-for-gremlin-eventstrategy-usage
spmallette
spmallette2y ago
thanks - i didn't know that problem existed. EventStrategy is a nice idea but i'm not sure it's a good general purpose feature of TinkerPop. It also has the problem of being Java-only and it can't work remotely.
Napsetern
NapseternOP2y ago
Correct me if I'm wrong but you mean at the end in the status check in the transactionnalQueue ? If so no change noticed. So that means this default code will never trigger the listener a second time ?
graph.traversal().withStrategies(EventStrategy.build().eventQueue(new TransactionalEventQueue(graph)).addListener(new CustomListener()).create())
graph.traversal().withStrategies(EventStrategy.build().eventQueue(new TransactionalEventQueue(graph)).addListener(new CustomListener()).create())
since we never "re add" the transactionnal listener ?
Bo
Bo2y ago
Unfortunately, yes So yeah... it's now very cumbersome to use EventStrategy with JanusGraph. I would just use https://docs.janusgraph.org/advanced-topics/transaction-log/ instead.
spmallette
spmallette2y ago
yeah...i think this is a good point. i'm starting to feel like this sort of a use case is best left to individual graph systems to provide as a feature rather than it be a TinkerPop one.
Want results from more Discord servers?
Add your server