concurrent-users-service

Description

The purpose of this service is to track devices that are actively streaming media for each user.

This service will not enforce limits, it will simply keep track of actively streaming devices per user based on the information provided by the clients. Clients can choose to enforce limits based on the information provided by this service. Here is how this is accomplished.

Current Devices List

List of devices that are currently streaming media, maintained by this service for each user. If a user doesn't have a list that means the list is empty. The list can't grow longer than some system specified limit. The rules for the list are:

Always add devices to the tail and remove from the head of the list. There is a system specified limit beyond which the list can't grow. If we try to add a device that is already in the list, the device is moved from it's current location to the tail of the list. If we add a device that forces the list go grow beyond limit we have to remove another device from the list.

Start

Adds the device to the current devices list for the user. Called once by the client right before starting to view a stream. The rules for this method are:

Check

Checks if a given given device should be allowed to stream. This method will be called periodically by the clients while playing a stream to check if the device is still allowed to stream. The rules for this method are:

Clients

As stated before the concurrent users rules are enforced by clients by making sure they are following these rules:

  1. Always call start immediately before starting a stream.
  2. Continually call check while playing a stream and stop playing if and ONLY if HTTP Code 403 is returned (for all other codes, even error codes, the clients should continue playing).

Lets follow a sequence of calls to demonstrate how this will work. For the purspose of this example we assume limit=2 and (x, n) means request for user x on device n .

Seq Request Params State Return Description
0 x => [] Initial state
1 start (x, 1) x => [1] 200 Starting streaming on 1
2 check (x, 1) 200 OK to continue streaming on 1
3 start (x, 1) 200 Starting new stream on 1
4 check (x, 1) 200 OK to continue streaming on 1
5 start (x, 2) x => [2, 1] 200 Starting streaming on 2
6 check (x, 2) 200 OK to continue streaming on 2
7 check (x, 1) 200 OK to continue streaming on 1
8 start (x, 1) x => [1, 2] 200 Starting new stream on 1
9 check (x, 1) 200 OK to continue streaming on 1
10 check (x, 2) 200 OK to continue streaming on 2
11 start (x, 3) x => [3, 1] 200 Starting streaming on 3
12 check (x, 1) 200 OK to continue streaming on 1
13 check (x, 2) 403 CAN'T continue streaming on 2
14 check (x, 3) 200 OK to continue streaming on 3
15 start (x, 2) x => [2, 3] 200 Starting new stream on 2
16 check (x, 1) 403 CAN'T continue streaming on 1
17 check (x, 2) 200 OK to continue streaming on 2
18 check (x, 3) 200 OK to continue streaming on 3

As you can see every time when 3rd device starts streaming (seq. 11 and 15) it causes the 1st (least recent) device to stop streaming next time check is called (seq. 13 and 16).

State

Sate or Current Devices List will be stored in Redis cluster with userId as the key.

API

As discussed there are two API calls start and check to mutate and check the state. Both accept the same parameters.

Request

Parameter Required Type Description
Authorization Yes Header Auth PASSWORD token from Authorization HTTP Header
deviceId Yes URL NFL Device ID

Endpoints

URL Method Description
/v1/concurrentusers POST Start
/v1/concurrentusers GET Check

Response

POST Response

HTTP Code Description Body
200 Success None
500 Internal Error {"errorCode": "code", "errorMessage": "message" }

GET Response

HTTP Code Description Body
200 Success No Body
403 Forbidden No Body
500 Internal Error {"errorCode": "code", "errorMessage": "message" }

Examples:

Request Response
POST /v1/concurrentusers?deviceId=deviceA 200
GET /v1/concurrentusers?deviceId=deviceA 200
POST /v1/concurrentusers?deviceId=deviceB 200
GET /v1/concurrentusers?deviceId=deviceA 200
GET /v1/concurrentusers?deviceId=deviceB 200
GET /v1/concurrentusers?deviceId=deviceC 403
POST /v1/concurrentusers?deviceId=deviceC 200
GET /v1/concurrentusers?deviceId=deviceA 403
GET /v1/concurrentusers?deviceId=deviceB 200
GET /v1/concurrentusers?deviceId=deviceC 200

Note that all requests must also include NFL Auth PASSWORD Token in Authorization Header.