Skip to content

Add some design diagrams #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
################################################################################

[workspace]
exclude = [".vscode/*", ".github/*", "tools/*", ".gitignore"]
exclude = [".vscode/*", ".github/*", "tools/*", ".gitignore", ".devcontainer/*"]
members = ["up-subscription", "up-subscription-cli"]
resolver = "2"

Expand Down
108 changes: 108 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This codebase is heavily work in progress - among the next things to do and inve
- Is it expected that a uEntity can register more than one custom topic receiving update notifications?
- Is it supposed to be possible to register remote uuris as notification topics?
- Should remote UUris be excluded from all listeners except `subscribe` and `unsubscribe`?
- Do we need update/change notifications when remote SubscriptionResponses come in?

## Getting Started

Expand Down Expand Up @@ -71,3 +72,110 @@ To run (and auto-build if required) the container, in the project root run
```console
docker-compose up
```

## Design

USubscription service implementation is a three-tiered design, with the following layers:

- UTransport listeners, which link USubscription service methods to a specific transport implementation
- USubscription service, which is called from the listeners and performs input validation as well as high-level business logic orchestration; it acts as a frontend for
- subscription and notification manager actors, which contain the book-keeping and core business logic around subscriptions and notifications

The overall usubscription service implementation comprises the following building blocks:

```mermaid
block-beta
columns 3

transport(("UTransport")):3
space:3

block:listeners:3
SubscribeListener
UnsubscribeListener
etcListener
end
space:3

usubscription:3
space:3

subscription_manager:1
space:1
notification_manager:1
space:3

task("remote_(un)subscribe")
space:2

transport--"rpc call"-->listeners
listeners-->usubscription
usubscription--"mpsc channel"-->subscription_manager
usubscription--"mpsc channel"-->notification_manager
subscription_manager--"spawn"-->task

classDef smaller font-size:small;
class SubscribeListener,UnsubscribeListener,etcListener smaller
class task smaller
```

$~$

A basic interaction flow for a client requesting a subscription is illustrated below:

```mermaid
sequenceDiagram
actor UTransport
box WhiteSmoke USUbscription Service
participant subscribe listener
participant usubscription
participant subscription_manager
participant notification_manager
end

UTransport-->>+subscribe listener: SubscriptionRequest
subscribe listener->>usubscription: subscribe()

activate usubscription
usubscription->>subscription_manager: send(SubscriptionEvent::AddSubscription)
activate subscription_manager
subscription_manager-->>subscription_manager: validate and store subscription info

alt is local topic
subscription_manager-->>usubscription: send(SubscriptionStatus::SUBSCRIBED)

else is remote topic
subscription_manager-->>usubscription: send(SubscriptionStatus::SUBSCRIBE_PENDING)

create participant remote_subscribe
subscription_manager-->>remote_subscribe: spawn()
deactivate subscription_manager
remote_subscribe-->>UTransport: send remote SubscriptionRequest
UTransport-->>remote_subscribe: remote SubscriptionResponse

# remote_subscribe->>+notification_manager: send(NotificationEvent::StateChange)
# notification_manager-->>UTransport: send(Update) to default notification channel
# loop Every custom notification
# notification_manager-->>UTransport: send(Update) custom channel
# end
# notification_manager-->>-remote_subscribe: send(())

activate subscription_manager
destroy remote_subscribe
remote_subscribe-->>subscription_manager: send(RemoteSubscriptionEvent::RemoteTopicStateUpdate)
subscription_manager-->>subscription_manager: update subscription info
end
deactivate subscription_manager

usubscription->>subscribe listener: SubscriptionResponse
subscribe listener-->>UTransport: SubscriptionResponse

usubscription->>+notification_manager: send(NotificationEvent::StateChange)
notification_manager-->>UTransport: send(Update) to default notification channel
loop Every custom notification
notification_manager-->>UTransport: send(Update) custom channel
end
notification_manager-->>-usubscription: send(())
deactivate usubscription

```