From 06992b5ea103cfc67baffa10cb15c50d4fd886cd Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Mon, 31 Jan 2022 18:48:01 +0100 Subject: [PATCH 1/6] First draft of the Events adr. --- docs/ocis/adr/0015-events.md | 89 ++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 docs/ocis/adr/0015-events.md diff --git a/docs/ocis/adr/0015-events.md b/docs/ocis/adr/0015-events.md new file mode 100644 index 00000000000..4b3b77348c7 --- /dev/null +++ b/docs/ocis/adr/0015-events.md @@ -0,0 +1,89 @@ +--- +title: "15. oCIS Event System" +weight: 15 +date: 2022-02-01T12:56:53+01:00 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/ocis/adr +geekdocFilePath: 0015-events.md +--- + +* Status: proposed +* Deciders: @butonic, @micbar, @dragotin, @c0rby, @wkloucek +* Date: 2022-01-21 + +## Context and Problem Statement + +### Overview + +To be able to implement simple, flexible and independant inter server communication there is the idea to implement an event system in oCIS. A service can send out events which are received by one or more other services. The receiving service can cause different kind of actions based on the event by utilizing the information that the event carries. + +### Example: EMail Notification + +A simple example is the notification feature for oCIS: Users should receive an email when another user shares a file with them. The information, that the file was shared should go out as an event from the share manager, carrying the information which file was shared to which receiver. A potential notification service that really sends out the email listens to these kind of events and sends the email out once on every received event of that specific type. + +## Decision Drivers + +- Events are supposed to simplify things and raise flexibility, also considering extensions that are not directly controlled by the ownCloud project. +- Events should bring flexibility in the implementation of sending and receiving services. +- Events should not obsolete other mechanisms to communicate, ie. grpc calls. +- Sending an event has to be as little resource consuming for the sender as possible. +- Events are never user visible. + +## Considered Options + +1. Lightweight Events with Event Queue and "At most once" QoS +2. As 1., but with "At least once" QoS + +## Options + +### 1. Lightweight Events with Event Queue and "At most once" QoS + +Reva will get a messaging service that is available to all services within oCIS and Reva. It is considered as one of the mandatory services of the oCIS system. If the messaging backend is not running, neither Reva nor oCIS can be considered healthy and should shut down. + +All oCIS- and Reva-services can connect to the messaging bus and send so called events. The sender gets an immediate return if handing the event to the message bus was succesful or not. + +The sender can not make any assumptions about when the message is delivered to any receiving service, nor if zero, one or many services are listening to that event. + +#### Event Data + +Events are identified by their namespace and their respective name. The namespace is delimited by dots and starts with either "reva" or "ocis" or an future extension name. It is followed by the name of the sending service and an unique name of the event. + +Example: `ocis.ocdav.delete` - an event with that name sent out if an WebDAV DELETE request arrived in the oCDav service. + +An event can carry a payload which is encoded as json object. (See for example [NATS](https://docs.nats.io/using-nats/developer/sending/structure) ). There are no pre defined members in that object, it is fully up to the sender which data will be included in the payload. Receivers must be robust to deal with changes. + +#### Quality of Service + +Events are sent with "At most once" quality of service. That means, if a receiver is not present at the moment of publishing it might not receive the event. That requires that the receiver must have functionality to back up the situation that events were missed. Given that the event queue can be considered the backbone of the system, it is unlikely that it is not running. + +#### Transactions + +The described way of inter service communication with events is not transactional. It is not supposed to be, but only provides a lightweight, loosely coupled way to "inform". + +If transactions are required, proper GRPC API calls with synchron reply are to be used. Another way would be to build asynchronous flows with request- and reply events in an asynchronous way. That is only recommended for special cases. + +#### Pros +- Simple setup +- Flexible way of connecting services +- "State of the art" pattern in microservices architectures + +#### Cons +- Over engineering: Can we do without an extra message queue component? +- Messages might get lost, so that eventual consistency is endangered +- Message queue needs to be implemented in Reva + +### 2. Lightweight Events with Event Queue and "At-least once" QoS + +Exactly as described above, but with a higher service level quality. + +#### Pros +- Better service level: Messages do not get lost. +- + + + +## Decision Outcome + + +### Design + From 2d9d67ef8c8e713aa89e572a124ef717738834d9 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Tue, 1 Feb 2022 16:58:57 +0100 Subject: [PATCH 2/6] Update docs/ocis/adr/0015-events.md Co-authored-by: David Christofas --- docs/ocis/adr/0015-events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ocis/adr/0015-events.md b/docs/ocis/adr/0015-events.md index 4b3b77348c7..4972ff17efa 100644 --- a/docs/ocis/adr/0015-events.md +++ b/docs/ocis/adr/0015-events.md @@ -15,7 +15,7 @@ geekdocFilePath: 0015-events.md ### Overview -To be able to implement simple, flexible and independant inter server communication there is the idea to implement an event system in oCIS. A service can send out events which are received by one or more other services. The receiving service can cause different kind of actions based on the event by utilizing the information that the event carries. +To be able to implement simple, flexible and independent inter service communication there is the idea to implement an event system in oCIS. A service can send out events which are received by one or more other services. The receiving service can cause different kinds of actions based on the event by utilizing the information that the event carries. ### Example: EMail Notification From 700ba907ac22f3b529a14675d6617a585cc450ef Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Tue, 1 Feb 2022 16:59:07 +0100 Subject: [PATCH 3/6] Apply review feedback. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: David Christofas Co-authored-by: Jörn Friedrich Dreyer --- docs/ocis/adr/0015-events.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/ocis/adr/0015-events.md b/docs/ocis/adr/0015-events.md index 4972ff17efa..89afb4ac353 100644 --- a/docs/ocis/adr/0015-events.md +++ b/docs/ocis/adr/0015-events.md @@ -17,13 +17,13 @@ geekdocFilePath: 0015-events.md To be able to implement simple, flexible and independent inter service communication there is the idea to implement an event system in oCIS. A service can send out events which are received by one or more other services. The receiving service can cause different kinds of actions based on the event by utilizing the information that the event carries. -### Example: EMail Notification +### Example: Email Notification -A simple example is the notification feature for oCIS: Users should receive an email when another user shares a file with them. The information, that the file was shared should go out as an event from the share manager, carrying the information which file was shared to which receiver. A potential notification service that really sends out the email listens to these kind of events and sends the email out once on every received event of that specific type. +A simple example is the notification feature for oCIS: Users should receive an email when another user shares a file with them. The information, that the file was shared should go out as an event from a storage provider or share manager, carrying the information which file was shared to which receiver. A potential notification service that sends out the email listens to these kind of events and sends the email out once on every received event of that specific type. ## Decision Drivers -- Events are supposed to simplify things and raise flexibility, also considering extensions that are not directly controlled by the ownCloud project. +- Events are supposed to decouple services and raise flexibility, also considering extensions that are not directly controlled by the ownCloud project. - Events should bring flexibility in the implementation of sending and receiving services. - Events should not obsolete other mechanisms to communicate, ie. grpc calls. - Sending an event has to be as little resource consuming for the sender as possible. @@ -42,7 +42,7 @@ Reva will get a messaging service that is available to all services within oCIS All oCIS- and Reva-services can connect to the messaging bus and send so called events. The sender gets an immediate return if handing the event to the message bus was succesful or not. -The sender can not make any assumptions about when the message is delivered to any receiving service, nor if zero, one or many services are listening to that event. +The sender can not make any assumptions when the message is delivered to any receiving service. Depending on the QoS model (as proposed as alternatives in this ADR) it might even be not guaranteed that the event is delivered at all. Also, the sender can not know if zero, one or many services are listening to that event. #### Event Data @@ -60,11 +60,12 @@ Events are sent with "At most once" quality of service. That means, if a receive The described way of inter service communication with events is not transactional. It is not supposed to be, but only provides a lightweight, loosely coupled way to "inform". -If transactions are required, proper GRPC API calls with synchron reply are to be used. Another way would be to build asynchronous flows with request- and reply events in an asynchronous way. That is only recommended for special cases. +If transactions are required, proper synchronous GRPC API calls should be used. Another way would be to build asynchronous flows with request- and reply events as in [saga pattern](https://microservices.io/patterns/data/saga.html). That is only recommended for special cases. #### Pros - Simple setup - Flexible way of connecting services +- Stateless event queue - "State of the art" pattern in microservices architectures #### Cons @@ -78,8 +79,9 @@ Exactly as described above, but with a higher service level quality. #### Pros - Better service level: Messages do not get lost. -- +#### Cons +- Stateful event system with higher cost in terms of compute and storage. ## Decision Outcome From ee8c97bb9d481a0e68a72bbf009f41ad7ec250ef Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Wed, 2 Feb 2022 16:42:56 +0100 Subject: [PATCH 4/6] add more pros and cons --- docs/ocis/adr/0015-events.md | 39 ++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/docs/ocis/adr/0015-events.md b/docs/ocis/adr/0015-events.md index 89afb4ac353..562c9827541 100644 --- a/docs/ocis/adr/0015-events.md +++ b/docs/ocis/adr/0015-events.md @@ -17,17 +17,17 @@ geekdocFilePath: 0015-events.md To be able to implement simple, flexible and independent inter service communication there is the idea to implement an event system in oCIS. A service can send out events which are received by one or more other services. The receiving service can cause different kinds of actions based on the event by utilizing the information that the event carries. -### Example: Email Notification +### Example: Email Notification A simple example is the notification feature for oCIS: Users should receive an email when another user shares a file with them. The information, that the file was shared should go out as an event from a storage provider or share manager, carrying the information which file was shared to which receiver. A potential notification service that sends out the email listens to these kind of events and sends the email out once on every received event of that specific type. ## Decision Drivers -- Events are supposed to decouple services and raise flexibility, also considering extensions that are not directly controlled by the ownCloud project. -- Events should bring flexibility in the implementation of sending and receiving services. -- Events should not obsolete other mechanisms to communicate, ie. grpc calls. -- Sending an event has to be as little resource consuming for the sender as possible. -- Events are never user visible. +* Events are supposed to decouple services and raise flexibility, also considering extensions that are not directly controlled by the ownCloud project. +* Events should bring flexibility in the implementation of sending and receiving services. +* Events should not obsolete other mechanisms to communicate, ie. grpc calls. +* Sending an event has to be as little resource consuming for the sender as possible. +* Events are never user visible. ## Considered Options @@ -63,29 +63,34 @@ The described way of inter service communication with events is not transactiona If transactions are required, proper synchronous GRPC API calls should be used. Another way would be to build asynchronous flows with request- and reply events as in [saga pattern](https://microservices.io/patterns/data/saga.html). That is only recommended for special cases. #### Pros -- Simple setup -- Flexible way of connecting services -- Stateless event queue -- "State of the art" pattern in microservices architectures + +* Simple setup +* Flexible way of connecting services +* Stateless event queue +* "State of the art" pattern in microservices architectures #### Cons -- Over engineering: Can we do without an extra message queue component? -- Messages might get lost, so that eventual consistency is endangered -- Message queue needs to be implemented in Reva + +* Over engineering: Can we do without an extra message queue component? +* Messages might get lost, so that eventual consistency is endangered +* A service needs to hold more state to ensure consistency +* Message queue needs to be implemented in Reva ### 2. Lightweight Events with Event Queue and "At-least once" QoS Exactly as described above, but with a higher service level quality. #### Pros -- Better service level: Messages do not get lost. + +* Better service level: Messages do not get lost +* Simplifies the design of the microservices because the events are "fire-and-forget" +* Events would be idempotent. If a service goes down the events will stay in the queue until they are consumed #### Cons -- Stateful event system with higher cost in terms of compute and storage. +* Stateful event system with higher cost in terms of compute and storage +* The queue could become a bottleneck and needs to be scaled ## Decision Outcome - ### Design - From 8da7fcfd0da14e9a156b589ce1b46cba4fcdd4aa Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Thu, 3 Feb 2022 12:12:23 +0100 Subject: [PATCH 5/6] Update docs/ocis/adr/0015-events.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jörn Friedrich Dreyer --- docs/ocis/adr/0015-events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ocis/adr/0015-events.md b/docs/ocis/adr/0015-events.md index 562c9827541..ba312aec55c 100644 --- a/docs/ocis/adr/0015-events.md +++ b/docs/ocis/adr/0015-events.md @@ -54,7 +54,7 @@ An event can carry a payload which is encoded as json object. (See for example [ #### Quality of Service -Events are sent with "At most once" quality of service. That means, if a receiver is not present at the moment of publishing it might not receive the event. That requires that the receiver must have functionality to back up the situation that events were missed. Given that the event queue can be considered the backbone of the system, it is unlikely that it is not running. +Events are sent with "At most once" quality of service. That means, if a receiver is not present at the moment of publishing it might not receive the event. That requires that the sender must have functionality to back up the situation that events were missed. Given that the event queue can be considered the backbone of the system, it is unlikely that it is not running. #### Transactions From a7187036f6f8f8e6198ca25c0bc469b0e4204b3f Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Thu, 3 Feb 2022 13:34:27 +0100 Subject: [PATCH 6/6] clarify where we need state --- docs/ocis/adr/0015-events.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/ocis/adr/0015-events.md b/docs/ocis/adr/0015-events.md index ba312aec55c..9c6ceb2e904 100644 --- a/docs/ocis/adr/0015-events.md +++ b/docs/ocis/adr/0015-events.md @@ -54,7 +54,7 @@ An event can carry a payload which is encoded as json object. (See for example [ #### Quality of Service -Events are sent with "At most once" quality of service. That means, if a receiver is not present at the moment of publishing it might not receive the event. That requires that the sender must have functionality to back up the situation that events were missed. Given that the event queue can be considered the backbone of the system, it is unlikely that it is not running. +Events are sent with "At most once" quality of service. That means, if a receiver is not present at the moment of publishing it might not receive the event. That requires that the sender and the receiver must have functionality to back up the situation that events were missed. That adds more state to the services because they always need to behave like a [FISM](https://en.wikipedia.org/wiki/Finite-state_machine). Given that the event queue can be considered the backbone of the system, it is unlikely that it is not running. #### Transactions @@ -80,6 +80,10 @@ If transactions are required, proper synchronous GRPC API calls should be used. Exactly as described above, but with a higher service level quality. +#### Quality of Service + +Events are sent with "At least once" quality of service. That means the events will remain in the queue until they are received by all receivers. This puts more responsability on the event bus and adds state to the events. Given that the event queue can be considered the backbone of the system, it is required to be running. + #### Pros * Better service level: Messages do not get lost