这是一个两部分问题,首先是一个设计问题,而不是如何实现它,其次是Akka的一些实现问题。
我正在使用Scalatra构建一个REST服务端点,当被调用时,它将从多个源中提取图像,操纵它们并返回它们。这可能是一个相当长的运行过程,并且可能会更长,然后单个http请求/响应周期可以接受。
我对此的看法是,当调用时,我将启动一堆akka Actors来提取图像资源,让他们将结果交给Image processing Actors进行缩放等。初始请求本身会立即返回某种处理ID可用于对后续轮询调用另一个端点,该端点将在处理结果时返回结果,并带有一个标志,用于确定是否有更多结果可供客户端知道停止轮询。
我的问题如下:
实施部分
假设我最终得到了类似于上面的设计,我对Scalatra& amp; Akka(或任何演员范例)和我有几个问题。
好的,第一个是我认为的Scala / Scalatra特定问题。好的,我查看了akka http://www.scalatra.org/guides/async/akka.html上的Scalatra文档,在这个例子中,他们设置了应用程序引导程序,如下所示:
// Get a handle to an ActorSystem and a reference to one of your actors
val system = ActorSystem()
val myActor = system.actorOf(Props[MyActor])
// In the init method, mount your servlets with references to the system
// and/or ActorRefs, as necessary.
override def init(context: ServletContext) {
context.mount(new PageRetriever(system), "/*")
context.mount(new MyActorApp(system, myActor), "/actors/*")
}
我认为scalatra的引导在应用程序启动时发生一次,system.actorOf(Props [MyActor])是否为每个请求创建一个实例或一个实例?
其次,说我的MyActor类(或更明智的名字)做了以下事情:
class MyActor extends Actor {
def receive = {
//Find the [ImageSearchingActor] actor in akka registry and send search message
case initiateSearchRequest: InitiateSearchRequestMessage => TODO
//Find free [ImageProcessingActors] in akka registry and send each Image url to process
case imageInformationFound : ImageInformationFoundMessage => TODO
//Persist the result to a cache, or data store with the ProcessingId that all message will pass
case imageProcessed : ImageProcessedMessage => TODO
}
}
现在,在这种情况下,多个地方我将检索图像,因此几个Actors将抓取这些数据。当他们找到合适的图像时,将使用几个Actors来处理图像。如果我使用我的设计,那么我需要标记某个地方,对于给定的ProcessingId,没有更多处理过的图像可用。这意味着我需要知道所有图像搜索和图像处理参与者何时完成给定的ProcessingId。我该怎么做?
所以这是一个很大的问题,要消费的信息我希望它有意义。
干杯。克里斯。
答案 0 :(得分:3)
这里有几个问题。快速回答:
是的,我想是的。
您可能希望将一个Actor类用作聚合器,主控器或协调器,从而启动图像检索和图像处理Actor类。然后,聚合器包含用于何时可以认为整体计算完成的逻辑。互联网上有很多这种事情的例子,如果你想要具体的例子来匹配你正在做的事情,请确保你看看Akka 2.1.x的例子,因为这就是你可能需要的东西,如果你'重新使用当前的Scalatra代码库。
这可能是一个好主意。 Scalatra与Atmosphere框架集成,可以很容易地进行websocket / comet长轮询。你可以阅读in the docs。是否对您的应用程序有意义取决于很多因素,但值得关注。根据我的经验,套接字编程有时可能是惊人的,有时比它的价值更麻烦 - 例如,如果你经历了很多代理,例如,除非使用SSL,否则websockets存在问题。但是,看到信息一旦可用就被推送到客户端,这是一件很美妙的事情。
关于另一个问题,关于ActorSystem的创建:
在Scalatra中,您的控制器基于每个请求进行实例化;示例代码中的ActorSystem只被初始化一次。每当请求进入门时,都会创建一个新的控制器实例,并引用ActorSystem。
ActorSystem创建是a heavyweight operation,并且应该尽可能少地发生。