core-java icon indicating copy to clipboard operation
core-java copied to clipboard

Prohibit returning `Empty` from `@Assign` of `ProcessManager`s and introduce `Expect<..>` returning value instead

Open armiol opened this issue 6 years ago • 0 comments

Currently ProcessManagers may return Empty in response to a handled command. Even though it violates the command handler method contract (according to which an Event message must be returned), such a workaround is required.

In particular there is a scenario, in which a ProcessManager is used to communicate with external API. E.g. ArchiveFile command leads to the call to the API of Cloud Storage. The execution of such a command often cannot be propagated synchronously due to an async nature of 3rd-party API. Therefore it is not possible to return FileArchived event right away, and Empty is returned.

However, the semantics of Empty has nothing with the real state of things. In fact the signature


@Assign
Empty handler(ArchiveFile command) {...}

confuses more than tells.

It is proposed to disallow returning Empty results from the command handlers. And to support the cases such as the one described, an Expect<...> type for return results is to be introduced. E.g.

@Assign
Expect<FileArchived> handler(ArchiveFile command) {
    // ...
    return Expect.event(FileArchived.class);
}

Now we are much closer in describing of what really happened.

The Expect type — similar to Tuples — is in fact an Iterable holding a Message describing a type URL of the expected event:

public class Expect<M extends EventClass> implements Iterable<EventType> {...}

whereas EventType is a Protobuf value object:

message EventType {
     string type_url = 1 [(required) = true];
}

The Expect<..>-typed returning values should be taken into account by the system bounded context in the events corresponding the CommandLifecycle aggregate.

This issue will resolve the workaround introduced in #789.

armiol avatar Jul 25 '18 16:07 armiol