Route on Selection Input

How to write ESB3024 Router configurations to route on selection input, using CDN bandwidth and number of ongoing sessions as example.

This page describes how to write configuration for routing on bandwidth usage or number of ongoing sessions in Edgeware CDN:s by using the selection input API. For configuration in general, see Configuration.

For more details on the selection input API, see Selection Input.

Selection Input

The selection input API allows you to inject custom data, that can be used during routing, into the router. For this use case, we will use CDN bandwidth and the number of ongoing sessions to demonstrate the capabilities of the selection input API.

Imagine that we have a monitor constantly polling the bandwidth and ongoing sessions of hosts in a CDN. These values are injected into the selection input API as JSON packets:

{
  "edge-host-available-bps": 1000000000,
  "edge-host-ongoing-sessions": 300
}

These keys will end up in the router Lua context as “selection inputs”, arbitrary values or JSON objects that can be used to calculate routing weights.

The selection input variable edge-host-available-bps will be available through either selection_input.edge-host-available-bps or si('edge-host-available-bps'). The function si(si_var) fetches the selection input value if it exists, otherwise it returns 0. However, when comparing selection input variables with numbers, there are a number of built-in Lua functions that will simplify things, such as gt() and lt(). For a complete list and more details on these functions, see Built-in Functions.

Simple Example

$ confcli services.routing.rules -w
Running wizard for resource 'rules'

Hint: Hitting return will set a value to its default.
Enter '?' to receive the help string

rules : [
  rule can be one of
    1: allow
    2: consistentHashing
    3: contentPopularity
    4: deny
    5: firstMatch
    6: random
    7: rawGroup
    8: rawHost
    9: split
    10: weighted
  Choose element index or name: firstMatch
  Adding a 'firstMatch' element
    rule : {
      name (default: ): selection-input-routing
      type (default: firstMatch): ⏎
      targets : [
        target : {
          onMatch (default: ): edge-host
          rule (default: ): lt('edge_host_ongoing_sessions', 1000)
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): edge-host
          rule (default: ): gt('edge_host_available_bps', 5000000)
        }
        Add another 'target' element to array 'targets'? [y/N]: y
        target : {
          onMatch (default: ): offload-host
          rule (default: ): always()
        }
        Add another 'target' element to array 'targets'? [y/N]: ⏎
      ]
      onMiss (default: ): offload-host
    }
  Add another 'rule' element to array 'rules'? [y/N]: ⏎
]
Generated config:
{
  "rules": [
    {
      "name": "selection-input-routing",
      "type": "firstMatch",
      "targets": [
        {
          "onMatch": "edge-host",
          "condition": "lt('edge_host_ongoing_sessions', 1000)"
        },
        {
          "onMatch": "edge-host",
          "condition": "gt('edge_host_available_bps', 5000000)"
        },
        {
          "onMatch": "offload-host",
          "condition": "always()"
        }
      ]
    }
  ]
}
Merge and apply the config? [y/n]: y
$ confcli services.routing.entrypoint selection-input-routing
services.routing.entrypoint = 'selection-input-routing'
{
  "content_server": {
    "http_enable": true,
    "http_port": 80,
    "https_enable": true,
    "https_port": 443
  },
  "cdns": [
    {
      "id": "edge-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    },
    {
      "id": "offload-cdn",
      "http_port": 80,
      "https_port": 443,
      "redirecting": false,
      "manifest_availability_check": {
        "enabled": false,
        "session_group_ids": []
      }
    }
  ],
  "hosts": [
    {
      "id": "edge-host",
      "cdn_id": "edge-cdn",
      "host": "edge-host.example"
    },
    {
      "id": "offload-host",
      "cdn_id": "offload-cdn",
      "host": "offload-host.example"
    }
  ],
  "routing": {
    "id": "routing-table",
    "member_order": "sequential",
    "members": [
      {
        "id": "edge-host-sessions-available",
        "host_id": "edge-host",
        "weight_function": "return (lt('edge_host_ongoing_sessions', 1000) ~= 0) and 1 or 0"
      },
      {
        "id": "edge-host-bandwith-available",
        "host_id": "edge-host",
        "weight_function": "return (gt('edge_host_available_bps', 5000000) ~= 0) and 1 or 0"
      },
      {
        "id": "offload",
        "host_id": "offload-host",
        "weight_function": "return 1"
      }
    ]
  }
}