2

akka-stream-and-http-experimental1.0で遊んでいます。これまでのところ、HTTP 要求を受け入れて応答できるユーザー サービスができました。また、アポイントメントを管理できるアポイントメントサービスも予定しています。予約するには、既存のユーザーである必要があります。予約サービスは、ユーザーが存在するかどうかをユーザー サービスに確認します。これは明らかに HTTP 経由で実行できますが、予約サービスがユーザー サービスにメッセージを送信するようにしたいと考えています。akka-httpこれに慣れていないので、メッセージを送受信するためにアクターを (抽象化として) 使用する方法が明確ではありません。ドキュメントにはActorRefandについての言及がありますが、前者と後者の例はありません。私のコードは次のようになり、Githubにあります。ActorPublisher

trait UserReadResource extends ActorPlumbing {
  val userService: UserService
  val readRoute = {
  // route stuff
  }
}

trait ActorPlumbing {
  implicit val system: ActorSystem
  implicit def executor: ExecutionContextExecutor
  implicit val materializer: Materializer

  def config: Config
  val logger: LoggingAdapter
}

trait UserService { // Implemented by Slick and MongoDB in the backend
  def findByFirstName(firstName: String): Future[immutable.Seq[User]]
}

object UserApp extends App with UserReadResource with UserWriteResource with ActorPlumbing {
  override implicit val system = ActorSystem()
  override implicit def executor = system.dispatcher
  override implicit val materializer = ActorMaterializer()

  override def config = ConfigFactory.load()
  override val logger = Logging(system, getClass)

  private val collection = newCollection("users")
  val userRepository = new MongoDBUserRepository(collection)
  val userService: UserService = new MongoDBUserRepositoryAdapter(userRepository) with UserBusinessDelegate { 
    // implicitly finds the executor in scope. Ain't that cute?
    override implicit def executor = implicitly
  } 

  Http().bindAndHandle(readRoute ~ writeRoute, config.getString("http.interface"), config.getInt("http.port"))
}

編集:メッセージを送信する方法を見つけました。これは、を使用して実行できますSource.actorRef。これは、メッセージをストリームに送信するだけです。私がやりたいのは、ルート ハンドラー クラスが応答を受け取ることです。そうすれば、予約サービスを作成するときに、そのアクターはユーザー サービス アクターを呼び出して、例のユーザー ルート ハンドラーと同じ方法で応答を受け取ることができます。擬似コード:

val src = Source.single(name) \\ How to send this to an actor and get the response

編集2:@yardenaの回答に基づいて、次のことを思いつきましたが、最後の行はコンパイルされません。私のアクター パブリッシャーは、でラップされ、 としてルート ハンドラーに配信されるとFuture推測している を返します。PromiseFuture

get {
  parameters("firstName".?, "lastName".?).as(FindByNameRequest) { name =>
    type FindResponse = Future[FindByNameResponse]

    val src: Source[FindResponse, Unit] = Source.actorPublisher[FindResponse](businessDelegateProps).mapMaterializedValue {
      _ ! name
    }
    val emptyResponse = Future.apply(FindByNameResponse(OK, Seq.empty))

    val sink = Sink.fold(emptyResponse)((_, response: FindResponse) => response)

    complete(src.runWith(sink)) // doesn't compile
  }
}
4

2 に答える 2

1

を使用することになりましたActor.ask。単純。

于 2015-09-29T07:30:38.240 に答える