2009-08-21 2 views
4

첫 번째 질문이 너무 길기 때문에 별도의 질문으로 요청합니다. 액터 기반 응용 프로그램의 아키텍처에 대한 또 다른 내용입니다. 나는 4 개 별도의 구성 요소 및 절차에 필요한 그들 사이의 상호 작용이이 코드에서스칼라 액터로 실제로 애플리케이션 작성하기 II

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); 
    } 
} 

: 응용 프로그램을 통해 메시지 경로를 추적

이의 자바 코드의 조각을 보자 deleteTrades은 잘 정의되어 있습니다. 그것은 완전히 방법 deleteTrades에 포함되어 있습니다.

Actor으로 모델링하고 4 명의 개별 액터로 4 개의 구성 요소를 대체하면 절차에 무엇이 포함되는지 어떻게 추적 할 수 있습니까? 나는 !? 연산자를 사용하여 피할 수있어 특히한다면, 그것은 내가하는 다음 등 등의 코드 추가로 메시지를 보낼 것이다 나의 PersistenceActor에 메시지 GetTradesAndDelete를 보내는 것, 내 PermissionActor에 메시지 ConditionalDelete를 전송됩니다 가능성이 높습니다 삭제를 처리하려면 내 응용 프로그램에 걸쳐 흩어져있을 것입니다.

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

이전 질문과 마찬가지로 사람들이 어떻게이 문제를 해결합니까? 이 모든 것을 추적 할 수있는 훌륭한 모델링 도구가 있습니까? 사람들이 사용합니까 !? 너무 많은 구성 요소를 Actor s으로 돌리고 있습니까?

답변

6

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, SendCancelReportsUpdateWithDeletedTrades과 같은 응답이 예상되지 않으면 반환 메시지의 기능을 전달할 필요가 없습니다. 우리가 답을 요구하는 메시지에 대한 매개 변수로 메시지를 반환하는 함수를 기대하고 있기 때문에

, 우리는 다음과 같은 특성을 정의 할 수 있습니다 :

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

Daniel - 'DeleteTradesPermissions'의 클래스 정의를 보여줄 수 있습니까? 그것은 (나는 당신이 그들에게 카레 가루를다는 것을 몰랐습니다) 계급입니까? 자신의 추출기를 정의 했습니까? 그렇다면 어떻게? –

+0

음,이 코드는 실제로 작동하지 않습니다. 그것은 하나의 예입니다. 부분 적용을 강요하는 누락 된 "_"이 있음을 알았습니다. 나는 이것이 커링에 필요하지 않다고 생각했습니다. 그러나 나는 작은 일로 끝낼 수 있다고 확신합니다. 여기, 나는 뭔가를 만들었고, 나는 그것을 게시 할 것이다. –

1

배우 고려하지 않고 기존의 서비스 구성 요소를 대체하는 데 사용되어서는 안된다.

우리가 요즘 쓰는 대부분의 서비스 구성 요소는 교육을 통해 무국적자입니다. 무국적 서비스 구성 요소는 액터보다 관리하기 쉽습니다 (메시지 클래스 등은 제외). 배우와 비교할 때 부족한 것 중 하나는 비동기 실행입니다. 그러나 클라이언트가 대부분의 시간 동 기적으로 결과를 반환 할 것으로 예상 할 때 동기식 상태 비 저장 서비스 구성 요소는 작업에 적합합니다.

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

액터는 메시지를 처리하는 동안 수행 된 모든 차단 처리에주의해야합니다. 액터는 메시지를 순차적으로 처리하기 때문에 "act()"내부에서 I/O를 기다리는 동안 차단 될 때마다 사서함의 다른 메시지를 처리 ​​할 수 ​​없습니다. 여기서 사용하는 스칼라 관용구는 실제 차단 작업을 수행하는 또 다른 임시 액터를 시작하는 것입니다. 이 안티 패턴은 이벤트 기반 (반응) 액터에 더 많은 영향을 미칩니다. 이벤트 기반 액터가 피기 백으로 쓰레드를 차단하기 때문입니다.

내가 수집 할 수있는 것부터, 서비스 구성 요소에 대한 네 건의 호출이 모두 차단 될 수 있으므로 액터로 변환 할 때 해당 배율을 조정해야합니다.

+0

@walter; 네가 내 질문에 대답했는지 모르겠다. 나는 배우가 어떻게 작동하는지 완벽하게 잘 알고 있으며 일반적인 Java 코드를 비동기식 및 비 차단형 액터 코드로 변환하는 문제를 설명하려고했습니다. 즉, 응용 프로그램 전체에 분산 된 절차 논리를 어떻게 추적합니까? –

관련 문제