2013-04-13 18 views
5

这是一个两部分问题,首先是更多的设计问题,而不是如何实现它,其次是Akka的一些实现问题。Akka,Scalatra和Web状态问题

我正在使用Scalatra来构建REST服务终点,当被调用时会从多个来源中提取图像,操纵它们并返回它们。这可能是一个长时间运行的过程,并且可能会比单个http请求/响应周期更长。

我对此的看法是,当调用完成后,我将启动一堆akka Actor来拉取图像资源,并让它们将结果交给Image Processing Actors进行缩放等。初始请求本身会返回立即可以使用某种处理ID来处理后续轮询呼叫到另一个终点,这些终点将在处理结果时返回结果,并带有一个标志以确定是否有更多结果可供客户知道停止轮询。

我的问题,如下:

  1. 是否从设计的角度来看这个有意义吗?
  2. 如果我使用这种方法,那么每个后续检索处理图像的请求都必须具有某种状态意识,以了解客户端已收到的图像。你将如何管理这个状态?
  3. 我从来没有看过这个,但是长期运行的彗星式HTTP请求比在这种情况下进行轮询更有意义吗?

实现部分

假设我结束了类似上述设计,我很新的Scalatra的&阿卡(或任何演员范式),我有几个问题。

好吧,首先是一个斯卡拉/斯卡拉特的具体问题我认为。好吧,我看着Scalatra的文档上阿卡http://www.scalatra.org/guides/async/akka.html,在这个例子中,他们设置的应用程序自举如下:

// 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的的Bootstrap在应用程序启动时发生一次,所以不system.actorOf(道具[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 
    } 
} 

现在,在这种情况下,多有多个地方我会被检索图像等几位演员将被抓这个数据。当他们找到合适的图像时,将使用几个演员来处理图像。如果我使用我的设计,那么我需要标记某个给定ProcessingId的地方,没有更多的处理图像可用。这意味着我需要知道所有图像搜索和图像处理参与者何时完成给定的ProcessingId。我该怎么做呢?

所以这是一个很多问题,消耗的信息,我希望它是有道理的。

干杯。克里斯。

回答

3

这里有很多问题。快速回答:

  1. 是的,我这么认为。

  2. 您可能希望使用一个Actor类作为聚合器,主控或协调器,它们启动图像检索和图像处理Actor类。然后聚合器包含了什么时候你的整体计算可以被认为完成的逻辑。如果你想要具体的例子来匹配你正在做的事情,请确保你看看Akka 2.1.x的例子,因为这就是你可能需要的东西,重新使用当前的Scalatra代码库。

  3. 这可能是一个好主意。 Scalatra与Atmosphere框架进行了整合,这使得websocket/comet长轮询非常容易。你可以阅读约in the docs。是否适合您的应用取决于很多因素,但值得一看。就我的经验而言,套接字编程有时可能会让人惊叹,有时候会比其值得多麻烦 - 例如,如果你经历了很多代理,websockets就会出现问题,除非使用SSL。尽管如此,看到信息一旦可用就会被推送到客户端,这是一件很美妙的事情。

到了另外一个问题,关于ActorSystem创作:

在Scalatra的,您的控制器上的每个请求的基础实例化;您的示例代码中的ActorSystem只会初始化一次。每当请求进入门时,都会创建一个新的控制器实例,并引用ActorSystem。

演员系统的创建是a heavyweight operation,应该发生几次,你可以摆脱。

+0

非常完整的答案,谢谢。我现在认为彗星对此没有意义,因为这些请求将来自多个来源,我不想强​​加给他们。我会将此标记为正确的,但我错过了ActorSystem如何实例化Actor的观点。这是由于我问我的问题,在重读:-)时很愚蠢。 – Owen

+0

所以我问system.actorOf(Props [MyActor])是否会为每个请求创建一个新的MyActor,但显然它不会。但如果我没有将对MyActor的引用传递给控制器​​,并且只是引用了ActorSystem,那么每次都会调用actorOf创建一个新实例?如果是的话,我如何控制创建者的数量?理想情况下,我希望有一群这些人可供选择。实际上,再次想到,我应该再阅读一些文档,并停止提问:-) – Owen

+0

我想我听起来有点负面的插座。请记住,在websocket不能保持稳定的情况下,Atmosphere会回退到长轮询状态,所以它们仍然值得一试。 – futurechimp