0

皆さん、私は次のマップと構造タイプを定義しました:

type Mergeable = { def mergeFrom(data: Array[Byte]): com.google.protobuf.GeneratedMessageLite }
  val dispatchMap = Map(
    1 -> (ZombieSighting.defaultInstance.asInstanceOf[Mergeable], "akka://UlyssesAgenda/user/ServerCore/DispatchTarget")
  )

基本的に、私が行っているのは、「protobufメッセージタイプ1をネットワークから読み取ったときに、バイトからZombieSightingを作成し、指定された文字列で見つかったアクターにディスパッチする」というマップを定義することです。

つまり、これは私が今日持っているコードであり、メッセージとアクターを作成し、メッセージをアクターに送信します。

val dispatchInfo = dispatchMap.get(messageType)
val theMessage = dispatchInfo.map { _._1.mergeFrom(theBytes) }.get
val actorPath = dispatchInfo.map { _._2 } 
val targetActor = actorPath.map { SocketServer.system.actorFor(_) }
targetActor.map { _ ! theMessage }

私がこれを見るとき、私が考えることができるのは、これがどのように機能しないプログラミングの行数であるかということだけであり、これを行うためのはるかにエレガントな方法があると思わずにはいられません。タプルをパラメーターとして受け取り、変更されたタプルを返す関数を記述できることは知っていますが、ここでは、クリーンな慣用的なスカラに関して何も買わないと思います。

私の直感では、「dispatchMap.get(messageType)」で実行できる単一のマップステートメントがあり、tuple._2に基づくAkkaアクターのインスタンスと、tuple._1に基づくマージされたprotobufオブジェクトが得られます。

誰かがこのコードをポン引きして行数を減らし、より機能的にする方法を提案できますか?例えば

val (targetActor, theMessage) = ????
targetActor ! theMessage

編集:これがリファクタリングの私の最初の試みです..これはそれを行うための「スカラの方法」ですか?

val (msg, actor) = dispatchMap.get(messageType).map {
    case (m:Mergeable, path:String) => 
        (m.mergeFrom(theBytes), SocketServer.system.actorFor(path) )
}.get
actor ! msg

編集2:以下のコメント投稿者が提案したバージョンですが、これが本当に慣用的なものかどうかはわかりません。

  def dispatchMessage: IO.Iteratee[Unit] =
    repeat {
    for {
        (messageType, byteString) <- readMessage
    } yield {
        for (
            (protoMessage, actorPath) <- dispatchMap.get(messageType);
            theMessage = protoMessage.mergeFrom(byteString.toArray);
            targetActor = SocketServer.system.actorFor(actorPath) )
        yield 
            targetActor ! theMessage
    }
}

4

1 に答える 1

3

コードは次のように記述されている可能性があります。

val akkaResponseFuture =
  for ((bytes, actorPath) <- dispatchMap.get(messageType);
       theMessage         <- bytes.mergeFrom(theBytes);
       targetActor        =  SocketServer.system.actorFor(actorPath))
  yield
    targetActor ! theMessage

これは正しくないかもしれません。サンプルは自己完結型ではないため、動作するコードを作成しようとせずに実行しました。また、theBytesどこにも定義されていません。

しかし、私はあなたがそれを明確にして合理化するために理解のために使うことができるとかなり確信しています。

于 2013-02-15T02:24:46.787 に答える