Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Commit

Permalink
feat(ceb-inversion-core): improve documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
tmorin committed Dec 23, 2021
1 parent bba32d2 commit 3fb12c2
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 104 deletions.
3 changes: 2 additions & 1 deletion book/SUMMARY.md
Expand Up @@ -11,7 +11,8 @@
- [Messages](messaging/messages.md)
- [Gateway](messaging/gateway.md)
- [Inversion integration](messaging/inversion.md)
- [Implementations](messaging/implementations.md)
- [Reference Implementation](messaging/reference.md)
- [Moleculer Implementation](messaging/moleculer.md)
- [Adapters](messaging/adapters.md)
- [Elements](elements/README.md)
- [ElementBuilder](elements/ElementBuilder.md)
Expand Down
103 changes: 0 additions & 103 deletions book/messaging/implementations.md

This file was deleted.

Binary file added book/messaging/moleculer-balanced-microlith.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/messaging/moleculer-balanced-monolith.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions book/messaging/moleculer.md
@@ -0,0 +1,59 @@
# The Moleculer implementation

> The Moleculer implementation is defined in the NPM package [@tmorin/ceb-messaging-moleculer](https://www.npmjs.com/package/@tmorin/ceb-messaging-moleculer).
The [Moleculer] implementation leverages on the features provided by the microservices framework.

## Management of Commands and Queries

There is one [Moleculer service] per command or query types.
For instance, the command type `CommandA` will be managed by the service `CommandA`.

About commands, each service provides two [Moleculer actions]: `execute` and `executeAndForget`.
The first one executes the command handler and return the result.
The second one just executes the command handler at the next clock thick.
For instance, the command type `CommandA` can be executed within the Moleculer world with the actions `CommandA.execute` and `CommandA.executeAndForget`.
Each action accepts only one parameter: the command.

About queries, each service provides only one action: `execute`.
The action executes the query handler and return the result.
For instance, the query type `QueryA` can be executed within the Moleculer world with the action `QueryA.execute`.
The action accepts only one parameter: the query.

## Management of Events

The Events are managed by a single [Moleculer service]: `EventBus`.
Each time an Event is published, the type of the [Moleculer event] is `EventBus.<MESSAGE_TYPE>`.
For instance, when the Event `EventA` is published, the Moleculer event name is `EventBus.EventA`.

By default, the implementation publish messages using the _balanced_ mode.
That means, each _balanced_ event will be processed by only one `EventBus` Moleculer service instance within the cluster.

The default mode works well for monoliths where the logic is replicated in each node of the cluster.

![Event Balancer and Monolith](moleculer-balanced-monolith.png)

However, for Microliths or even Microservices, the `EventBus` instances have to arrange in logical groups.
The group name of `MoleculerEventBus` instances can be provided by constructor.

![Event Balancer and Microlith](moleculer-balanced-microlith.png)

## The Inversion Module

The package provides an Inversion Module which can be used to create the MoleculerGateway instance and register it on the registry.

Create a container with the default module behavior, i.e. a ServiceBroker is expected in the registry:
```typescript
{{#include ../../packages/ceb-book-samples/src/messaging/moleculer-inversion-registrykey.ts}}
```

Create a container with a provided ServiceBroker instance.
In that case, the provided ServiceBroker will be registered in the registry.
```typescript
{{#include ../../packages/ceb-book-samples/src/messaging/moleculer-inversion-instance.ts}}
```

[Moleculer]: https://moleculer.services
[Moleculer service]: https://moleculer.services/docs/0.14/actions.html
[Moleculer actions]: https://moleculer.services/docs/0.14/actions.html
[Moleculer event]: https://moleculer.services/docs/0.14/events.html
89 changes: 89 additions & 0 deletions book/messaging/moleculer.puml
@@ -0,0 +1,89 @@
@startuml moleculer-balanced-monolith
!include ../reference.puml
!global $LIB_BASE_LOCATION="../../.gdiag/plantuml-libs"
!global $IMAGE_BASE_PATH="../../.gdiag/plantuml-libs/"
Title("Event Balancer and Monolith", "The Moleculer implementation")
package node_a as "node 1" {
card component_a [
CommandA (Meleculer Service)
--
emit("EventBus.EventA", ...)
]
card eventbus_a [
EventBus (Meleculer Service)
--listeners--
EventBus.EventA
EventBus.EventB
]
}
package node_b as "node 2" {
card eventbus_b [
EventBus (Meleculer Service)
--listeners--
EventBus.EventA
EventBus.EventB
]
card component_b [
CommandA (Meleculer Service)
--
emit("EventBus.EventA", ...)
]
}
package node_c as "node 3" {
card eventbus_c [
EventBus (Meleculer Service)
--listeners--
EventBus.EventA
EventBus.EventB
]
card component_c [
CommandA (Meleculer Service)
--
emit("EventBus.EventA", ...)
]
}
component_a --> eventbus_b : send to only one EventBus
node_a -[hidden]- node_b
node_b -[hidden]- node_c
@enduml

@startuml moleculer-balanced-microlith
!include ../reference.puml
!global $LIB_BASE_LOCATION="../../.gdiag/plantuml-libs"
!global $IMAGE_BASE_PATH="../../.gdiag/plantuml-libs/"
Title("Event Balancer and Microliths", "The Moleculer implementation")
rectangle context_a as "Bounded Context A" {
card eventbus_a [
EventBus (Meleculer Service)
group: Bounded Context A
--listeners--
EventBus.EventA
]
card component_a [
CommandA (Meleculer Service)
--
emit("EventBus.EventA", ...)
]
}
rectangle context_b_1 as "Bounded Context B" {
card eventbus_b_1 [
EventBus (Meleculer Service)
group: Bounded Context B
--listeners--
EventBus.EventA
EventBus.EventB
]
}
rectangle context_b_2 as "Bounded Context B" {
card eventbus_b_2 [
EventBus (Meleculer Service)
group: Bounded Context B
--listeners--
EventBus.EventA
EventBus.EventB
]
}
component_a --> eventbus_b_1 : send to only one EventBus for the Bounded Context B
component_a -r-> eventbus_a : send to only one EventBus for the Bounded Context A
eventbus_b_1 -[hidden]r- eventbus_b_2
@enduml
50 changes: 50 additions & 0 deletions book/messaging/reference.md
@@ -0,0 +1,50 @@
# The reference implementation

> The reference implementation is defined in the NPM package [@tmorin/ceb-messaging-simple](https://www.npmjs.com/package/@tmorin/ceb-messaging-simple).
The reference implementation relies on an in-memory and single process approach.
So that, the implementation is free of network or any other concerns related to distributed systems.

## The SimpleGateway

A SimpleGateway instance can be got from the following three approaches: the global instance, the factory method or the constructor.

### The global instance

A global instance of the SimpleGateway is available from the static field `SimpleGateway.GOBAL`.
It's a lazy property, in fact the instance is only created once at its first get.

```typescript
{{#include ../../packages/ceb-book-samples/src/messaging/implementation-create_global.ts}}
```

### The factory method

A SimpleGateway instance can be easily created using the factory method, i.e. the static method `SimpleGateway.create()`.
The method returns a fresh new SimpleGateway instance at each call.

```typescript
{{#include ../../packages/ceb-book-samples/src/messaging/implementation-create_factory.ts}}
```

### The constructor

The constructor approach provides a fine grain control of the Gateway dependencies: the CommandBus, the QueryBus, the EventBus and the GatewayObserver.

```typescript
{{#include ../../packages/ceb-book-samples/src/messaging/implementation-create_constructor.ts}}
```

## The Inversion Module

The package provides an Inversion Module which can be used to create (optionally) and register it on the registry.

Create a container with the default module behavior, i.e. the SimpleGateway will be created from scratch automatically:
```typescript
{{#include ../../packages/ceb-book-samples/src/messaging/implementation-inversion-default.ts}}
```

Create a container with a provided SimpleGateway instance:
```typescript
{{#include ../../packages/ceb-book-samples/src/messaging/implementation-inversion-global.ts}}
```
4 changes: 4 additions & 0 deletions book/reference.puml
Expand Up @@ -39,6 +39,10 @@ skinparam {
RectangleBorderColor #2e3440
RectangleBorderThickness 1

NodeFontColor #2e3440
NodeBorderColor #2e3440
NodeBorderThickness 1

PackageFontName Architects Daughter
PackageFontStyle normal
PackageBorderColor #2e3440
Expand Down

0 comments on commit 3fb12c2

Please sign in to comment.