문제

첫 번째 질문이 너무 길어서 따로 질문을 드립니다.행위자 기반 애플리케이션의 아키텍처에 관한 또 다른 것입니다.

애플리케이션을 통해 메시지 경로 추적

Java 코드를 살펴보겠습니다.

public void deleteTrades(User user, Date date) {
    PermissionSet ps = permissionService.findPermissions(user)
    if (ps.hasPermission("delete")) {
        Set<Trade> ts = peristence.findTrades(date);
        reportService.sendCancelReports(ts);
        positionService.updateWithDeletedTrades(ts);
    }
}

이 코드에는 4개의 별도 구성 요소가 있으며 절차에 필요한 이들 간의 상호 작용이 필요합니다. deleteTrades 잘 정의되어 있습니다.메소드에 완전히 포함되어 있습니다. deleteTrades.

이것을 모델링하면 Actor4개의 구성 요소를 4개의 개별 액터로 교체하는 경우 절차에 포함된 내용을 어떻게 마음속으로 추적할 수 있습니까?특히 내가 !? 교환원, 그럼 내가 메시지를 보낼 것 같아 ConditionalDelete 나에게 PermissionActor, 메시지를 보내게 됩니다. GetTradesAndDelete 나에게 PersistenceActor 그런 다음 추가 메시지 등을 보냅니다.삭제를 처리하는 코드는 내 애플리케이션 전체에 흩어져 있습니다.

이는 또한 거의 모든 액터가 (메시지를 전달하기 위해) 다른 모든 액터에 대한 핸들이 필요하다는 것을 의미합니다.

이전 질문에서처럼 사람들은 이 문제를 어떻게 처리합니까?이 모든 것을 추적할 수 있는 좋은 모델링 도구가 있습니까?사람들이 사용합니까? !? 너무 많은 구성 요소를 Actor에스?

도움이 되었습니까?

해결책

확실히 5가지 구성 요소를 사용합니다.특정 작업을 처리하는 액터가 있고 오케스트레이터도 있습니다.

물론 여러분이 알아야 할 질문은 이것을 어떻게 비동기식으로 연결하느냐는 것입니다.실제로는 다소 쉽지만 코드를 모호하게 만들 수 있습니다.기본적으로 각 구성 요소에 원하는 응답을 보냅니다.

react {
  case DeleteTrades(user,dates) => 
    PermissionService ! FindPermissions(user, DeleteTradesPermissions(dates) _)
  case DeleteTradesPermissions(dates)(ps) =>
    if (ps hasPermission "delete")
      Persistence ! FindTrades(date, DeleteTradesTradeSet _)
  case DeleteTradesTradeSet(ts) =>
    ReportService ! SendCancelReports(ts)
    PositionService ! UpdateWithDeletedTrades(ts)
}

여기서는 첫 번째 반환 답변에 "날짜"를 전달하기 위해 커링을 사용합니다.상호 작용과 관련된 매개 변수가 많은 경우 진행 중인 모든 트랜잭션에 대한 정보를 로컬 HashSet에 유지하고 답변을 받을 때 해당 정보를 찾는 데 사용할 토큰을 전달하는 것이 더 나을 수 있습니다.

이 단일 액터는 여러 동시 작업을 처리할 수 있습니다.이 특별한 경우에는 거래 삭제만 하면 됩니다. 그러나 처리할 다양한 작업을 원하는 만큼 추가할 수 있습니다.한 작업에 필요한 데이터가 준비되면 해당 작업이 계속됩니다.

편집하다

다음은 이러한 클래스를 정의하는 방법에 대한 실제 예입니다.

class Date
class User
class PermissionSet

abstract class Message
case class DeleteTradesPermission(date: Date)(ps: PermissionSet) extends Message
case class FindPermissions(u: User, r: (PermissionSet) => Message) extends Message

FindPermissions(new User, DeleteTradesPermission(new Date) _)

카레링과 함수에 대한 몇 가지 설명입니다.클래스 DeleteTradesPermission 당신이 통과할 수 있도록 카레입니다 Date 그 위에 다른 기능을 추가하여 PermissionSet.이것이 응답 메시지의 패턴입니다.

이제 수업은 FindPermissions 두 번째 매개변수로 함수를 받습니다.이 메시지를 받은 행위자는 반환 값을 이 함수에 전달하고 Message 답변으로 보내드립니다.이 예에서 메시지에는 Date, 호출 배우가 보낸 것, 그리고 PermissionSet, 응답하는 배우가 제공하는 것입니다.

다음과 같이 답변이 기대되지 않는 경우 DeleteTrades, SendCancelReports 그리고 UpdateWithDeletedTrades 이 예제의 목적에 따라 반환 메시지의 함수를 전달할 필요가 없습니다.

응답이 필요한 메시지에 대한 매개변수로 메시지를 반환하는 함수가 필요하므로 다음과 같은 특성을 정의할 수 있습니다.

trait MessageResponse1[-T1] extends Function1[T1, Message]
trait MessageResponse2[-T1, -T2] extends Function2[T1, T2, Message]
...

다른 팁

고려 사항 없이 기존 서비스 구성 요소를 대체하는 데 행위자를 사용해서는 안 됩니다.

요즘 훈련을 통해 작성하는 대부분의 서비스 구성 요소는 상태 비저장입니다.상태 비저장 서비스 구성 요소는 행위자보다 관리하기가 더 쉽습니다(메시지 클래스 없음 등).하지만 액터와 비교할 때 부족한 것 중 하나는 비동기 실행입니다.그러나 클라이언트가 결과가 대부분 동기식으로 반환되기를 기대하는 경우에는 동기식 상태 비저장 서비스 구성 요소가 해당 작업에 적합합니다.

액터는 관리할 내부 상태가 있을 때 적합합니다.내부 상태에 액세스하고 경쟁 조건을 걱정하기 위해 "act()" 내부에서 동기화를 수행할 필요가 없습니다.하는 한 "!?" "act ()"내부에 사용되지 않으므로 교착 상태도 최소화되어야합니다.

행위자는 메시지를 처리하는 동안 수행되는 차단 처리에 주의해야 합니다.행위자는 자신의 메시지를 순차적으로 처리하기 때문에 "act()" 내부에서 I/O를 기다리면서 차단될 때마다 사서함에 있는 다른 메시지를 처리할 수 없습니다.여기서 사용할 Scala 관용구는 실제 차단 작업을 수행하는 또 다른 임시 행위자를 시작하는 것입니다.이 안티패턴은 이벤트 기반 행위자가 피기백되는 스레드도 차단하므로 이벤트 기반(반응) 행위자에게 더욱 영향을 미칩니다.

내가 수집한 바에 따르면 서비스 구성 요소에 대한 네 가지 호출 모두 잠재적으로 차단되므로 액터로 변환할 때 크기를 조정하도록 주의를 기울여야 합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top