Open Solido opened 3 years ago
/cc @michael-simons
Hi @Solido Thanks for your kind feedback.
Those that example help you? https://github.com/michael-simons/neo4j-from-the-jvm-ecosystem/blob/master/quarkus-reactive/src/main/java/org/neo4j/examples/jvm/quarkus/reactive/movies/PeopleRepository.java#L29-L48
If so, it should be included in a similar fashion in the starter doc.
As a beginner any material is premium to help grasp concept and best practices.
Here is the kotlin translation from the official Quarkus neo4j example and I wonder
.publisher(session.writeTransaction(tx -> tx.run(query, parameters).records())))
)fun <T> read(query: String, action: Action<T>): Multi<T> =
Multi.createFrom().resource(driver::rxSession) { rxs ->
rxs.readTransaction { tx ->
val rs = tx.run(query.trimIndent())
Multi.createFrom().publisher(rs.records()).map {
action(it)
}
}
}.withFinalizer(Consumer { Uni.createFrom().publisher<Void>(it.close()) })
Anyways Quarkus Team is so ... Reactive to provide help ;)
Thanks @michael-simons
Oh I just saw the root of your repo and implementation for every framework ! Great starter
My write method is naive replacement of read.
WriteTransaction()
instead of readTransactions()
but strangely rs.records does not hold any result so Multi is not triggered.
Driver got the WRITE Mode and any basic query will fail but OK on the browser
MATCH (d:Descriptable {key:"k55"}) RETURN d
fun <T> write(query: String, parameters: Map<String, Any> = emptyMap(), action: Action<T>): Multi<T> =
Multi.createFrom().resource(driver::rxSession) { rxs ->
rxs.writeTransaction { tx ->
val rs = tx.run(query, parameters)
Multi.createFrom().publisher(rs.records()).map { action(it) }
}
}.withFinalizer(Consumer { Uni.createFrom().publisher<Void>(it.close()) })
I See that the createFrom().resource
pattern is called to early… Fails on me as well … Need to investigate whether its on our side, quarkus or user :)
See my updated example.
With regard to write transaction we must use a hot stream:
Uni<Person> save(Person person) {
var query = ""
+ "MERGE (p:Person {name: $name})\n"
+ "SET p.born = $born\n"
+ "RETURN p\n";
var parameters = Map.<String, Object>of("name", person.getName(), "born", person.getBorn());
return Multi
.createFrom().resource(driver::rxSession, session -> session.writeTransaction(tx -> tx.run(query, parameters).records()))
.withFinalizer(rxSession -> {
return Uni.createFrom().publisher(rxSession.close());
})
.map(r -> asPerson(r.get("p").asNode()))
.transform().toHotStream() // Otherwise the created uni behaves weird. I guess this because due to `on completion event, a {@code null} item is fired by the produces {@link Uni}` (See `toUni` on Multi.)
.toUni();
}
Or don't transform the multi into a uni… That one behaves a bit odd. I do need a uni in my example however because I want to return a Uni<Response>
I would love to hear from @vietj or other folks having more knowledge than me about the subtle differences of Multi
and Uni
(Uni is not a publisher). Julien: The behavior I observe that the finalizer is executed before the actual inner Multi completes when I use toUni
on the whole thing without converting it into a hot stream.
Apart from that, your code looks good to me…
Description
The current documentation is very helpful providing an example for full async read using mutiny but an example on how to write would help a lot.
In my case I am stuck because simply replacing readtransaction() by writetransaction() will not work since rs.records never call the publisher since they are absent from the RxResult as opposed to a Read Transaction
Thank you !