You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2021/01/07 04:08:20 UTC

[james-project] 05/05: JAMES-3457 ADR for Mailbox/changes

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 463516db2f7091f6b48f7158fd3b18ccb824a65e
Author: LanKhuat <dl...@linagora.com>
AuthorDate: Mon Dec 7 15:49:15 2020 +0700

    JAMES-3457 ADR for Mailbox/changes
---
 ...map-push-with-mailbox-changes-implementation.md | 99 ++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/src/adr/0045-support-jmap-push-with-mailbox-changes-implementation.md b/src/adr/0045-support-jmap-push-with-mailbox-changes-implementation.md
new file mode 100644
index 0000000..4c476b4
--- /dev/null
+++ b/src/adr/0045-support-jmap-push-with-mailbox-changes-implementation.md
@@ -0,0 +1,99 @@
+# 45. Support JMAP Push with Mailbox/changes implementation
+
+Date: 2020-12-08
+
+## Status
+
+Accepted (lazy consensus).
+
+## Context
+
+JMAP Push notifications allow clients to efficiently update (almost) instantly to stay in sync with data changes on the server. 
+
+In order to support this, we need to handle the **state** property that comes with JMAP get/set request. This means that James needs to be able 
+to record a new state for objects whenever a change happens as well as return the most recent state to the client when fetching objects. 
+
+First step is to implement Mailbox/changes. 
+
+## Decision
+
+We will implement a mechanism to record all the changes happening to Mailbox objects in the form of a list of **mailboxId**. When an event such as  
+created/updated/destroyed occur, or when message is appended to a mailbox we will store their **mailboxIds** along with a **state** object
+in a Cassandra table.  
+
+Each state will have a list of changes, and all the **mailboxId** will be stored as separated lists corresponding to the change which they represent: **created**, **updated**, **destroyed**.
+For the case when messages are appended to a mailbox, it will be counted as an updated event and that mailboxId should be stored in **updated** list. 
+
+Leveraging the **MailboxChanges** table, we can now fetch all the changes that have occurred since a particular **state**.
+
+States are stored in Cassandra as time based UUID (**TimeUUID**). This ensures that no conflicting changes will happen in the case when two or more events occur at the same point in time.
+**TimeUUID** also allows **state** to be sorted in chronological order.
+
+Components that need to be implemented:
+
+- MailboxChangesRepository: Allows storing and fetching the **state** along with the lists of **mailboxId** in **MailboxChanges** table.
+- MailboxChangeListener: Listens to changes and triggers the record creation in **MailboxChanges** table.
+- MailboxChangeMethod: Handles the **state** property, allowing client to fetch the changes since a particular state. 
+- MailboxSetMethod/MailboxGetMethod needs to query the MailboxChangesRepository for their states properties.
+ 
+## Example of a Mailbox/changes request/response
+
+**Request**
+
+```
+[["Mailbox/changes", {
+  "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+  "sinceState": "dd3721a6-b3ee-4884-8762-fccc0c576438"
+}, "t0"]]
+```
+
+**Response**
+
+```
+[["Mailbox/changes", {
+  "accountId": "29883977c13473ae7cb7678ef767cbfbaffc8a44a6e463d971d23a65c1dc4af6",
+  "oldState": "dd3721a6-b3ee-4884-8762-fccc0c576438",
+  "newState": "2433b670-3554-4f55-bab1-147848e89e5d",
+  "hasMoreChanges": false,
+  "created": [ 
+    "1", 
+    "2" 
+  ],
+ "updated": [],
+ "destroyed": []
+}, "t0" ]]
+```
+
+## Consequences
+
+- Due to the limitation of the event listening mechanism of the listeners, we can only store one change (one **mailboxId**) for each state instead of many.  
+However, by keeping the data type of changes as separated lists, we will be more opened for future improvements.        
+- Changes can only be fetched in a linear fashion from oldest to newest, as opposed to how it should prioritize newer changes first according to the spec.
+
+## Cassandra table structure
+
+Only one table is required:
+
+```
+TABLE mailbox_changes
+PRIMARY KEY accountId
+CLUSTERING COLUMN state
+COLUMN created
+COLUMN updated
+COLUMN destroyed
+COLUMN isCountChange
+ORDERED BY state
+```
+
+## References
+
+- [Support JMAP HTTP PUSH](https://issues.apache.org/jira/browse/JAMES-3457)
+- [Implement a MailboxChangeRepository](https://issues.apache.org/jira/browse/JAMES-3459)
+- [Implement a JMAP MailboxChangeListener](https://issues.apache.org/jira/browse/JAMES-3460)
+- [Implement Mailbox/changes method and related contract tests](https://issues.apache.org/jira/browse/JAMES-3461)
+- [Implement CassandraMailboxChangeRepository](https://issues.apache.org/jira/browse/JAMES-3462)
+- [Mailbox/get should handle state property](https://issues.apache.org/jira/browse/JAMES-3463)
+- [Mailbox/set should handle oldState & newState](https://issues.apache.org/jira/browse/JAMES-3464)
+- [Mailbox/changes updatedProperties handling](https://issues.apache.org/jira/browse/JAMES-3465)
+- [ADR for Mailbox/changes](https://github.com/apache/james-project/pull/276)
+


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org