DDD:如何通知聚合器有关聚合中无效但非特殊操作的信息

时间:2014-09-13 19:21:01

标签: domain-driven-design

我的域名是公共安全领域的呼叫处理,例如紧急呼叫警察。

使用案例:接听电话时的竞争条件

鉴于 - >两个操作员(接听电话的人)登录到系统
- >有一个来电紧急呼叫,显示在屏幕上的两个操作员上 何时 - >两个运营商同时发送AcceptCallRequest
然后 - >首先处理的AcceptCallRequest获胜 - >发送AcceptCallSuccessReply,第二个将失败并显示AcceptCallErrorReply

我的问题是:
我应该如何处理我的汇总中的第二个接受请求? 因为我需要通知应用服务(来电者)这个操作是不可能的 这应该是DomainEventException还是其他什么?

目前我有一个名为Conversation的聚合,它处理接受请求,如下面的代码所示。

前两项检查非常特别:

  • 如果对话已经结束,那应该已经是 删除
  • 如果操作员开始谈话,则无法进行 接受它,因为它已经由运营商拥有

但是由于种族条件可能会发生的情况如何:

  • 对话已被其他运营商接受 - > 我如何通知应用程序服务它应该 发送错误回复?这是域名活动吗?
  • 对话已被同一运营商接受 - >
    这是一个幂等操作,应该导致相同(成功) 作为第一个请求回复,你们有什么想法?

    public void accept(final Operator theAccepter, final Date theTimeWhenAccepted) throws InvalidConversationStateException {
        checkNotEnded(String.format("Conversation already ended when accept by %s", theAccepter)); // throws an exception
        checkNotAlreadyActiveBecauseStartedByOperator(String.format("Conversation was started by a operator when accept by %s", theAccepter)); // throws an exception
    
    if (!isAccepted()) {
        this.accepter = theAccepter;
        this.conversationState = ConversationState.ACTIVE;
        this.acceptedTime = Dates.copy(theTimeWhenAccepted);
    
        for (MediaStream mediaStream : mediaStreams) {
            mediaStream.accept(accepter);
        }
    
        raiseConversationAcceptedEvent(accepter);
    } else {
        raiseAcceptConversationNotAllowed(
                theAccepter == this.accepter
                        ? AcceptConversationNotAllowedReason.ALREADY_ACCEPTED_BY_OWN
                        : AcceptConversationNotAllowedReason.ALREADY_ACCEPTED_BY_OTHER);
    }
    

    }

我的应用服务(Saga)看起来像这样:

       registerEventHandler(
                ConversationAcceptedEvent.class,
                event -> sendSuccessResponse(request));
        registerEventHandler(
                AcceptConversationNotAllowedEvent.class,
                event -> sendErrorResponse(request, String.format("accept not allowed because %s", event.getReason()));

        Operator accepter = new Operator(request.getSessionId(), request.getSubscriber());
        try {
            conversation.accept(accepter, clock.now());
        } catch (Exception e) {
            sendErrorResponse(request, e.getMessage());
        }

0 个答案:

没有答案