메시지를 연기하는 가장 좋은 방법은 무엇입니까?

"getItems"메시지를받을 수있는 "ItemProvider"액터가 있습니다. ItemProvider는 프로젝트의 항목을 관리합니다. 따라서 프로젝트 A에 대한 항목을 요청하는 여러 "getItems"메시지와 프로젝트 B에 대한 항목을 요청하는 다른 "getItems"메시지를 가질 수 있습니다.

"itemProvider"가 처음으로 이러한 메시지를 받으면 실제로 항목을 가져 오기 위해 서비스를 호출해야합니다 (서비스가 퓨처를 반환하므로 액터를 차단하지 않습니다). 이 대기 기간 동안 다른 "getItems"메시지가 도착할 수 있습니다.

프로젝트 "ItemProvider"는 서비스에서받은 "Items"를 캐시합니다. 따라서 1 분의 로딩 시간이 지나면 즉시 항목을 제공 할 수 있습니다.

나는 "ItemProvider"가 Akka의 기능을 사용해야한다고 확신합니다. 하지만 당장 서비스 할 수없는 클라이언트를 어떻게 처리해야합니까?

다음 옵션을 생각할 수 있습니다.

  1. ItemProvider는 List pendingMessages를 보유합니다. 그리고 제공 할 수없는 메시지가이 목록에 추가됩니다. ItemProvider가 "준비"되면 보류중인 클라이언트를 처리합니다.

  2. ItemProvider는 메시지를 부모에게 다시 보냅니다. 그리고 부모는 메시지를 재발행합니다

  3. ItemProvider는 스케줄러를 사용합니다. 그리고 미래에 다시 메시지를받습니다.

  4. be는 사용하지 않고 AbstractFSM 클래스를 사용합니까?

    아무도 ItemProvider를 구현하는 가장 좋은 Akka 방법을 알고 있습니까?

cmbaxter

아래에서 요구 사항을 충족하도록 액터를 구성하는 한 가지 가능한 방법을 찾을 수 있습니다. 이 솔루션에서는 프로젝트별로 액터 인스턴스를 사용하여 해당 프로젝트에 특정한 항목을 캐시합니다. 그런 다음 프로젝트 항목을 가져오고 해당 프로젝트의 캐시를 처리하는 올바른 자식 액터에 위임하는 요청을 수신하는 라우팅 액터를 사용합니다. 실제 캐싱 행위자에서 캐시 할 항목이로드 될 때까지 요청을 연기하기 위해 stash / unstash를 사용했음을 알 수 있습니다 (코드에서 시뮬레이션 중입니다). 코드는 다음과 같습니다.

import akka.actor._
import scala.concurrent.Future
import akka.pattern._
import concurrent.duration._ 
import akka.util.Timeout

class ItemProviderRouter extends Actor{
  import ItemProvider._

  def receive = {
    case get @ GetItems(project) =>

      //Lookup the child for the supplied project.  If one does not
      //exist, create it
      val child = context.child(project).getOrElse(newChild(project))
      child.forward(get)
  }

  def newChild(project:String) = {
    println(s"creating a new child ItemProvider for project $project")
    context.actorOf(Props[ItemProvider], project)
  }

}

object ItemProvider{
  case class GetItems(project:String)
  case class Item(foo:String)
  case class LoadedItems(items:List[Item])
  case object ClearCachedItems
  case class ItemResults(items:List[Item])
}

class ItemProvider extends Actor with Stash{
  import ItemProvider._  

  //Scheduled job to drop the cached items and force a reload on subsequent request
  import context.dispatcher
  context.system.scheduler.schedule(5 minutes, 5 minutes, self, ClearCachedItems)

  def receive = noCachedItems

  def noCachedItems:Receive = {
    case GetItems(project) =>
      stash()      
      fetchItems(project)
      context.become(loadingItems)


    case ClearCachedItems =>
      //Noop
  }

  def loadingItems:Receive = {
    case get:GetItems => stash

    case LoadedItems(items) =>
      println(s"Actor ${self.path.name} got items to cache, changing state to cachedItems")
      context.become(cachedItems(items))
      unstashAll()    

    case ClearCachedItems => //Noop      
  }

  def cachedItems(items:List[Item]):Receive = {
    case GetItems(project) =>
      sender ! ItemResults(items)

    case ClearCachedItems =>
      println("Clearing out cached items")
      context.become(noCachedItems)       

    case other =>
      println(s"Received unexpected request $other when in state cachedItems")          
  }

  def fetchItems(project:String){
    println(s"Actor ${self.path.name} is fetching items to cache")

    //Simulating doing something that results in a Future
    //representing the items to cache    

    val fut = Future{
      Thread.sleep(5000)
      List(Item(s"hello $project"), Item(s"world $project"))
    }

    fut.map(LoadedItems(_)).pipeTo(self)
  }
}

그런 다음 테스트하려면 :

object ItemProviderTest extends App{
  import ItemProvider._
  val system = ActorSystem("test")
  import system.dispatcher
  val provider = system.actorOf(Props[ItemProviderRouter])

  implicit val timeout = Timeout(10 seconds)
  for(i <- 1 until 20){
    val afut = provider ? GetItems("a")
    val bfut = provider ? GetItems("b")

    afut onSuccess{
      case ItemResults(items) => println(s"got items list of $items for project a")
    }

    bfut onSuccess{
      case ItemResults(items) => println(s"got items list of $items for project b")
    }    
  }
} 

간단하게하기 위해 사용자 지정 라우터가 아닌 실제 행위자를 사용하여 라우팅을 수행하지만 성능 (즉, 사서함 히트)이 중요하다면 여기에서 사용자 지정 라우터를 구현할 수도 있습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Looper를 얻는 가장 좋은 방법은 무엇입니까?

분류에서Dev

JavaFX : 간단한 메시지를 표시하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

iPhone-UITextfield 아래에 오류 메시지를 표시하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

vuejs에서 Http Exception 오류 메시지를 처리하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

Amazon Web Services SQS에서 메시지를 폴링하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

예외 메시지를 구조화하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

창 닫기를 차단하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

해시를 병합하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

콘텐츠를 저장하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

Android TV 메뉴를 만드는 가장 좋은 방법은 무엇입니까?

분류에서Dev

앱 메모리에 이미지를 저장하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

스레드를 기다리는 가장 좋은 방법은 무엇입니까?

분류에서Dev

함수를 기다리는 가장 좋은 방법은 무엇입니까?

분류에서Dev

pst 파일 크기를 얻는 가장 좋은 방법은 무엇입니까

분류에서Dev

URL을 다시 작성하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

React Redux Store를 사용하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

코드를 정리하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

API를 변경하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

mysqldump를 압축하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

mysqldump를 압축하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

CSS를 정규화하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

MSI를 구축하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

removeSuffix ()를 작성하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

내 JAR API를 관리하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

ivar를 정의하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

ivar를 정의하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

Chrome 용 RamDisk를 활용하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

Spark를 배포하는 가장 좋은 방법은 무엇입니까?

분류에서Dev

Rails 코드를 복제하는 가장 좋은 방법은 무엇입니까?

Related 관련 기사

  1. 1

    Looper를 얻는 가장 좋은 방법은 무엇입니까?

  2. 2

    JavaFX : 간단한 메시지를 표시하는 가장 좋은 방법은 무엇입니까?

  3. 3

    iPhone-UITextfield 아래에 오류 메시지를 표시하는 가장 좋은 방법은 무엇입니까?

  4. 4

    vuejs에서 Http Exception 오류 메시지를 처리하는 가장 좋은 방법은 무엇입니까?

  5. 5

    Amazon Web Services SQS에서 메시지를 폴링하는 가장 좋은 방법은 무엇입니까?

  6. 6

    예외 메시지를 구조화하는 가장 좋은 방법은 무엇입니까?

  7. 7

    창 닫기를 차단하는 가장 좋은 방법은 무엇입니까?

  8. 8

    해시를 병합하는 가장 좋은 방법은 무엇입니까?

  9. 9

    콘텐츠를 저장하는 가장 좋은 방법은 무엇입니까?

  10. 10

    Android TV 메뉴를 만드는 가장 좋은 방법은 무엇입니까?

  11. 11

    앱 메모리에 이미지를 저장하는 가장 좋은 방법은 무엇입니까?

  12. 12

    스레드를 기다리는 가장 좋은 방법은 무엇입니까?

  13. 13

    함수를 기다리는 가장 좋은 방법은 무엇입니까?

  14. 14

    pst 파일 크기를 얻는 가장 좋은 방법은 무엇입니까

  15. 15

    URL을 다시 작성하는 가장 좋은 방법은 무엇입니까?

  16. 16

    React Redux Store를 사용하는 가장 좋은 방법은 무엇입니까?

  17. 17

    코드를 정리하는 가장 좋은 방법은 무엇입니까?

  18. 18

    API를 변경하는 가장 좋은 방법은 무엇입니까?

  19. 19

    mysqldump를 압축하는 가장 좋은 방법은 무엇입니까?

  20. 20

    mysqldump를 압축하는 가장 좋은 방법은 무엇입니까?

  21. 21

    CSS를 정규화하는 가장 좋은 방법은 무엇입니까?

  22. 22

    MSI를 구축하는 가장 좋은 방법은 무엇입니까?

  23. 23

    removeSuffix ()를 작성하는 가장 좋은 방법은 무엇입니까?

  24. 24

    내 JAR API를 관리하는 가장 좋은 방법은 무엇입니까?

  25. 25

    ivar를 정의하는 가장 좋은 방법은 무엇입니까?

  26. 26

    ivar를 정의하는 가장 좋은 방법은 무엇입니까?

  27. 27

    Chrome 용 RamDisk를 활용하는 가장 좋은 방법은 무엇입니까?

  28. 28

    Spark를 배포하는 가장 좋은 방법은 무엇입니까?

  29. 29

    Rails 코드를 복제하는 가장 좋은 방법은 무엇입니까?

뜨겁다태그

보관