0

リクエストのロギング/クリーンアップを行う前に、クライアントに応答を返送できるようにしたいと思います。

play 1.xでは、これは@Finallyアノテーションで可能でした。これらのアノテーションがアクションコンポジションに置き換えられたという投稿をいくつか読んだことがありますが、それを使用して@Finallyアノテーションをエミュレートする方法がわかりません。

カスタムアクションのすべてのロジックが完了した後にのみ、応答が返されるように思われます。

私は何かを逃したことがありますか、それともPlay 2.0でこれを行う方法はありませんか?

[わかりやすくするために編集]つまり、要求を受信して​​応答を送信した後、ロジックを実行できるようにしたいのです。したがって、次の形式のタイムラインを作成できるようにしたいと思います。

  1. クライアントがサーバーにリクエストを送信します
  2. サーバーは200応答を送り返し、クライアントはそれを受け取ります
  3. サーバーは追加の処理、ロギングなどを行います

play 1.xでは、@ Finallyを使用して追加の処理ロジックに注釈を付け、希望どおりに機能させることができると思います。

4

1 に答える 1

2

アクションコンポジションは仕事をするのに十分ではありませんが、アクションコンポジション+フューチャー、またはアクションコンポジション+アクターはこれを達成するための良い方法です。

アクション構成+未来

応答を生成し、非同期コンテキストでロギング/処理を起動し、並行して結果を送信します。

def LoggedAction(f: Request[AnyContent] => Result) = Action { request =>
  val result = f(request)
  concurrent.future(myLogAction(request, result))
  result
}

アクション構成+俳優

それを達成するためのよりクリーンな方法です。前の場合と同様に、応答を生成し、ロギング/処理イベントをアクターに送信し、並行して結果を送信します。

import play.api._
import play.api.mvc._
import play.libs._
import akka.actor._

object Application extends Controller with Finally {
  def index = LoggedAction { r =>
      Ok(views.html.index("Your new application is ready."))
  }
}

trait Finally {
  self: Controller =>

  lazy val logActor = Akka.system.actorOf(Props(new LogActor), name = "logActor")

  def LoggedAction(f: Request[AnyContent] => Result) = Action { request =>
    val result = f(request)         // Generate response
    logActor ! LogRequest(request)  // Send log event to LogActor
    println("-> now send page to client")
    result
  }

  case class LogRequest(request: Request[AnyContent]) 

  class LogActor extends Actor {
    def receive = {
      case LogRequest(req) => {
        println(req.host)
        // ....
      }
    }
  }
}

// Console
-> now send page to client
127.0.0.1:9000
于 2013-01-29T20:48:45.163 に答える