I would like to know if I can use tinkerpop within Akka Futures, so far when I commit my changes to the graph they don't get persisted.
I understand tinkerpop is a thread-local library which mean I'd need to set my thread again within the future ODatabaseRecordThreadLocal.INSTANCE.set(thread)
I tried the following method without success :
def test[T](graphChanges: => T): T = {
val thread = ODatabaseRecordThreadLocal.INSTANCE.get
try graphChanges finally {
ODatabaseRecordThreadLocal.INSTANCE.set(thread)
GraphPool.get("partitioned").commit
}
}
// collect tinkerpop frames
test {
future {
// add changes to my tinkerpop frames
}
}
I would like to have on Tinkerpop thread per play.mvc.Http.Context
Here is a sample project with what I want to achieve : https://github.com/D-Roch/tinkerpop-play
The problem is, that Tinkerpop works thread local. So your changes are only committed to the current thread. When creating Scala futures, you let the environment choose, in which thread the future will be executed. And the environment doesn't know better, so it chooses the wrong thread.
The problem is similar for Akka futures.
When creating a future, you are creating it with two parameters:
The second parameter is usually given as an implicit parameter. But you can override the default.
When creating futures dealing with Tinkerpop, use an execution context that runs every block in the same thread.
Example:
import scala.concurrent.ExecutionContext
import java.util.concurrent.Executors
implicit val ec=ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor)
future {
println(Thread.currentThread);
future {
println(Thread.currentThread)
}
}
This code prints out the same thread id twice on the console (tested with Java 7 and Scala 2.10.2.
Attention: Using such a small thread pool can easily lead to dead locks or starvation. Use it only for your Tinkerpop interaction.
You can either provide a special method tinkerpopFuture that takes a block as an parameter and returns a future that will run in the tinkerpop thread. Or you can create a special actor which encapsulates all tinkerpop interactions (and runs them with the special tinkerpop exection context).