CloudServices/Notifications/Push/Architecture

From MozillaWiki
Jump to: navigation, search

What the Client Does

  1. Log in to Firefox with BrowserID.
  2. Start Notifications client.
  3. Authenticate with Push Notification Service.
  4. Sync push URLs.
  5. Get stored messages.
  6. Get list of socket servers from Box Office.
  7. Connect to one of the socket servers, or backoff and retry.
  8. Get streaming messsages.
  9. Get new push URL (navigator.mozNotifcation.requestPermission()).
  10. Revoke push URLs (user action).
  11. Mark messages as read (synced with server).
  12. Maintain local DB of push URLs and site icons for displaying messages.

Storage

Storage is keyed off a token generated from the BrowserID assertion. For each user, we need to store a list of push URLs and a list of recent messages.

Push URLs need to be synced between user devices. They are persistent and only deleted by user request.

Recent messages are stored on the server to support syncing messages between devices. Messages will expire and be availble for garbage collection after min(three days, sender-provided TTL). Clients can mark a message as read after user action (clicking on a message or clearing it), and other clients will update their local state.

NB: when I talk about sync I don't necessarily mean Sync.

Server Components

All the good ideas are based off talks with Urban Airship. Each of the following sections can be built as a separate component so that no one piece can take down the whole system. They're partitioned based on the functionality they provide.

Client API

HTTP endpoint supporting basic client operations. Clients would come here on startup to sync push URLs and stored messages. New push URLs are created when a site asks for push permission.

  • Register client
  • Create/revoke push URLs
  • Sync push URLs
  • Get list of unread messages when a client comes online

Third-party site API

HTTP endpoint supporting third-party sites. Notifications come into the system and are passed on to the routing layer.

  • Accept messages from third-party sites
  • Pass messages to routing layer

Routing Layer

When a messages comes in through the API it needs to be routed to the correct socket server(s) to get pushed to a client. There may be zero, one, or many connected clients. Routing possibilities:

  • Registry server that tracks which socket server(s) a client is connected to, and then:
    • direct RPC to the socket server
    • pub/sub to a channel for that server
  • Open pub/sub: all socket servers listen to the same channel and pick out which messages they can send

Box Office (BO)

When a client wants to connect to a socket server, the client asks BO for a list of server IP addresses. BO returns multiple IP addresses for the client to connect to. The client should try them in the returned order (BO can order by decreasing free capacity). If the client can't connect, it should get a new list from the BO, using exponential backoff. If there are capacity problems BO can tell a client not to connect to any socket servers.

This could potentially be merged into the Client API component.

Socket Server

The socket servers hold open persistent client connections and pass messages to sockets with minimal latency. They can't be behind Zeus due to licensing and scalability issues.

  • Hold connections open to clients
  • Send messages to client
  • Send message-read to client
  • Receive message-read from client
  • Send push URL updates to client?
  • Track connection state and share with Box Office
  • Not behind Zeus