Route on Selection Input
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"
}
]
}
}