2014-10-11 14 views
5

Sau khi đã sử dụng Play! Khuôn khổ trong một thời gian, tôi đang dùng một cái nhìn đầu tiên để phun. Tôi bắt đầu từ một mẫu tôi tìm thấy trên GitHub, bây giờ tôi muốn sửa đổi nó nhưng nó không phải dễ dàng cho tôi để có được cách thức hoạt động.Gọi một diễn viên trong đường phun và đợi phản hồi của diễn viên

Tôi làm cách nào để đợi thông báo từ diễn viên trong mã bên dưới?

package api 

import akka.actor.ActorRef 
import scala.concurrent.ExecutionContext 
import spray.routing.Directives 
import core.ClassifierActor 

class ClassifierService(classifier: ActorRef)(implicit executionContext: ExecutionContext) 
    extends Directives with DefaultJsonFormats { 

    import ClassifierActor._ 

    implicit val classifyMessageFormat = jsonFormat4(ClassifyMessage) 

    val route = 
    path("classify") { 
     post { 
     handleWith { 
      // The ClassifierActor gets a ClassifyMessage and 
      // sends a ClassifiedMessage back to the sender. 
      // How can wait for the ClassifiedMessage here 
      // and send a HttpResponse back? 
      cm: ClassifyMessage => classifier ! cm 
      // ??? 
     } 
     } 
    } 

} 
+0

Tôi không viết mã định tuyến để tôi không biết cách tốt nhất nhưng bạn không bao giờ chờ đợi: thay vào đó bạn đưa yêu cầu cho một diễn viên hoặc có thể là một diễn viên được bao bọc trong tương lai gửi trả lời khi quá trình xử lý hoàn tất. – Rup

+0

Tôi mới sử dụng Spray, vì vậy tôi không thể nhận được bất kỳ lợi thế nào từ câu trả lời của bạn. Tôi thà cần một đoạn mã. – Max

Trả lời

12

Spray đã được dựa trên akka.io

Vì vậy, nếu bạn muốn chỉ để hoàn thành tuyến đường của bạn với phản ứng diễn viên, bạn có thể sử dụng mẫu hỏi

import akka.pattern.ask 
import scala.concurrent.duration._ 
implicit val timeout = Timeout(5 seconds) // needed for `?` below 

val route = 
    path("classify") { 
     post { 
     onComplete(actorResponse(yourActor, yourMessage)) { 
      complete(_) 
     } 
     } 
    } 

def actorResponse[T](actor: ActorRef, msg: ClassifyMessage): Future[T] = 
(actor ? msg).mapTo[T] 

Nếu bạn muốn chuyển tiếp yêu cầu mô hình diễn viên của bạn và hoàn thành tuyến đường ở đâu đó trong hệ thống diễn viên, bạn cần chuyển tiếp RequestContext tới các diễn viên. Có thể, điều này example có thể giúp bạn. Chúc may mắn!

+0

Cảm ơn! Bạn có thể thêm 'import scala.concurrent.Future' vì Java cũng có một tương lai. Và 'nhập khẩu akka.actor.Actor' chỉ vì nó cũng là cần thiết. – akauppi

+0

Một lưu ý quan trọng: người đó đã sử dụng diễn viên (xem "bộ phân loại: ActorRef" trong q). Nếu người ta đơn giản tìm kiếm một cách để logic phản ứng đa luồng, Tương lai [HttpResponse] là con đường để đi, không phải là diễn viên. Xem https://www.chrisstucchio.com/blog/2013/actors_vs_futures.html – akauppi

3

Hãy xem dự án ví dụ của tôi. This service sử dụng tương lai để hoàn thành các tuyến đường. Giống như Rup nhận xét, đó là thực tế xấu để chờ đợi một phản ứng. Trả về một tương lai ngay lập tức và để nó hoàn thành khi nó nhận được kết quả.

Trong ví dụ của bạn classifier ! cm đang sử dụng mẫu "cho biết" của diễn viên. Nó sẽ gửi một thông báo cm tới diễn viên classifier và tiếp tục. Nếu bạn muốn nó mong đợi một phản hồi trở lại trong tương lai, hãy sử dụng mẫu "yêu cầu": classifier ? cm. Trong phương thức nhận của tác giả cm của bạn, bạn sẽ trả lại một tương lai với sender ! responseMsg sẽ trở lại trong tương lai.

Các vấn đề liên quan