1

私は雇用主のために小さなツールを構築し、Akka 2+Scalaを使用してそれを実装しようとしています。

私がインターフェースしているシステムの1つにSOAPAPIがあり、これには興味深い実装があります。

- - リクエスト - - - -

クライアント----リクエスト---->サーバー

クライアント<---ReqAck-----サーバー

- - 応答 - - -

クライアント<---応答----サーバー

クライアント----応答確認---->サーバー

リクエストの追跡は、req-ackによって送信されたタスクIDを介して行われます。

私の質問はSOコミュニティへの質問であり、akkaの経験がある人は次のとおりです。

  • この特定のシナリオでakkaを使用してhttpメッセージを処理する理想的な方法は何でしょうか。Play-miniを優先して廃止されたように見えるAkka-Mistの例を見たことがあります。次に、akka2.0.3の一部としてライブラリを見つけることができないように見えるakka-camelがあります。配布なので、どのようなアプローチを取るべきかについて少し混乱しています。サーブレットの動作をakkaアクター内にカプセル化するための推奨される方法はありますか?

よろしくお願いします。

4

1 に答える 1

3

あなたの質問は非常に自由形式なので、私はあなたの要件についていくつかの仮定をします。

リクエストの想定:あるイベントで多くのリクエストが生成されます。

async-http-client(https://github.com/sonatype/async-http-client)をラップするアクターを持つルーターを作成します。async-http-clientがリクエストを完了すると、ReqAckに含まれているIDを持つメッセージがコーディネーションアクターに送信されます。コーディネーションアクターはIDを集約します。

以下は主に擬似コードですが、実際のAPIに十分近いため、不足している部分を特定できるはずです。

case class Request(url:String)
case class IDReceived(id:String)

case class RequestingActor extends Actor {

    override def receive = {
        case Request(url) => {
            //set up the async client and run the request
            //since it's async the client will not block and this actor can continue making generating more requests
        }
    }
}


class AsyncHttpClientResponseHandler(aggregationActor:ActorRef) extends SomeAsyncClientHandler {

    //Override the necessary Handler methods.

    override def onComplete = {
        aggregationActor ! IDReceived(//get the id from the response)
    }
}

class SomeEventHandlerClass { 

    val requestRouter = actorSystem.actorOf(Props[RequestingActor].withRouter(FromConfig(//maybe you've configured a round-robin router)), requestRouterName)

    def onEvent(url:String) {
        requestRouter ! Request(url)
    }

}

case class AggregationActor extends Actor {

    val idStorage = //some form of storage, maybe a Map if other information about the task ID needs to be stored as well.  Map(id -> other information)

    override def receive = {
        case IDReceived(id) => //add the ID to idStorage
    }
}

応答の前提:応答に含まれるデータを使用して何かを実行してから、IDを完了としてマークする必要があります。HTTPフロントエンドは、この1セットのメッセージのみを処理する必要があります。

Akka統合を備えたフレームワークを見つける代わりに、作成したAkkaネットワークにメッセージを送信する単純なHTTPフロントエンドを使用するだけです。play-miniを使用することで得られる利点は想像できません。また、作業の分離と制御を示す線の一部がわかりにくくなると思います。それは常に当てはまるわけではありませんが、あなたの質問に要件がないことを考えると、私は自分の意見の根拠となるものは他にありません。

case class ResponseHandlingActor extends Actor {

    val aggregationActor = actorSystem.actorFor(//the name of the aggregation router within the Actor System)

    override def receive = {
        case Response(data) => {
            //do something with the data.  If the data manipulation is blocking or long running it may warrant its own network of actors.
            aggregationActor ! ResponseReceived(//get the id from the response)
        }
    }
}

class ScalatraFrontEnd() extends ScalatraServlet {

    val responseRouter = actorSystem.actorOf(Props[RequestingActor].withRouter(FromConfig(//maybe you've configured a round-robin router)), requestRouterName)

    post("/response") {
        responseRouter ! Response(//data from the response)
    }

}

これに似たシステムを作成すると、関心の分離がうまくいき、処理が行われる場所を簡単に推測でき、システムを拡張したり拡張したりするための十分なスペースが得られます。

于 2012-09-26T12:59:43.437 に答える