4 ms·
A for-comprehension from our production code: for { createResult <- Graph.createPerson(person) _ <- Search.putAll[Person](createResult
by saryant 13y ago
A for-comprehension from our production code:
for {
createResult <- Graph.createPerson(person)
_ <- Search.putAll[Person](createResult \ "updated_nodes")
_ <- Search.deletePersons(createResult \ "deleted_nodes")
} yield {
Created(createResult \ "node")
}
That code asynchronously updates both ElasticSearch and Neo4j. Those functions all return Scala futures containing JSON values. First the new object is created in Neo and then the index in ES is updated accordingly. This is in a controller action in a Play project where it's critical to keep everything non-blocking. If everything is successful, Play returns a 201 result to the requestor, otherwise there are error handling functions elsewhere that kick in.
- NickPollard 13y agoScala derail: You might have an unintentional happens-before relationship in that example: The deletePersons call will end up being in the flatMap of the putAll[Person] call, which means it wont be started until the putAll finishes, when by the looks of it you could do both at once (only the createPerson needs to happen first). You might want to do something like this: for { createResult <- Graph.createPerson(person) } yield { val a = Search.putAll[Person](createResult \ "updated_nodes") val b = Search.deletePersons(createResult \ "deleted_nodes") for ( _ <- a; _ <- b ) yield Created(createResult \ "node") } (notice starting the computations outside of the second for-comprehension, then just waiting for them inside)
- saryant 13y agoGood catch. :) Our production code actually does handle the relationship correctly, I just wanted to simplify in my example.
- dilap 13y agoWhat happens if the process dies in between createPerson and the search stuff? Are the Neo4j results kept around w/ the search index left stale, or is there some sort of wrapping transaction around it all?