5

我想知道我是否可以在 Akka Futures 中使用 tinkerpop,到目前为止,当我将更改提交到图表时,它们不会被持久化。我知道 tinkerpop 是一个线程本地库,这意味着我需要在将来再次设置我的线程ODatabaseRecordThreadLocal.INSTANCE.set(thread)

我尝试了以下方法但没有成功:

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
  }
}

我想在每个 play.mvc.Http.Context 上都有 Tinkerpop 线程

这是一个我想要实现的示例项目:https ://github.com/D-Roch/tinkerpop-play

4

2 回答 2

7

问题

问题是,Tinkerpop 在本地工作线程。因此,您的更改仅提交给当前线程。创建 Scala 期货时,您让环境选择未来将在哪个线程中执行。而且环境不知道更好,所以它选择了错误的线程。

Akka 期货的问题与此类似。

未来在哪个线程中运行?

创建未来时,您使用两个参数创建它:

  1. 应该执行的块
  2. 应该执行块的执行上下文

第二个参数通常作为隐式参数给出。但是您可以覆盖默认值。

解决方案

在创建处理 Tinkerpop 的期货时,请使用在同一线程中运行每个块的执行上下文。

例子:

import scala.concurrent.ExecutionContext
import java.util.concurrent.Executors

implicit val ec=ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor)

future { 
    println(Thread.currentThread); 
    future {
        println(Thread.currentThread)
    }  
}

此代码在控制台上两次打印出相同的线程 ID(使用 Java 7 和 Scala 2.10.2 测试。

注意:使用这么小的线程池很容易导致死锁或饥饿。仅用于您的 Tinkerpop 交互。

您可以提供一个特殊的方法 tinkerpopFuture ,该方法将块作为参数并返回将在 tinkerpop 线程中运行的未来。或者,您可以创建一个特殊的 actor 来封装所有 tinkerpop 交互(并使用特殊的 tinkerpop 执行上下文运行它们)。

文学

于 2014-01-08T09:03:36.830 回答
4

这看起来不像是特定于 Tinkerpop 的任何东西,它看起来像是使用 Futures 所犯的一个常见错误。只需考虑这个片段:

try graphChanges finally { ... }

它本身看起来不错,但我也可以看到,graphChanges这里正在创造一个未来。所以...

  • graphChanges启动一个 Future,立即返回
  • try块完成并执行finally
  • 在此之前的某个时刻,或之后,或者可能是并行的,但几乎可以肯定是在另一个线程上,Future执行

我的建议是将异步逻辑test移到blocking. 像这样:

def test[T](graphChanges: => T): Future[T] = future {
  blocking {
    val tlocal = ODatabaseRecordThreadLocal.INSTANCE
    val dbrecord = tlocal.get

    try graphChanges finally {
      tlocal.set(dbrecord)
      GraphPool.get("partitioned").commit
    }
  }
}

// collect tinkerpop frames
test {
  // add changes to my tinkerpop frames
}
于 2014-01-02T17:29:25.750 回答