Solution 1 - ProspectOne/flexbalancer-js-docs GitHub Wiki

Solution 1: The Optimal Round Trip Time with The Monitor Availability.

The Case: we have the bunch of answers, that are inspected by our previously created Monitors. We need to get answer that has:

  • Corresponding Monitor online,
  • CDN provider availability for the last hour higher than 90%
  • The best CDN provider performance for the last hour.

In case of all monitors are down it should simply return a random answer. And if all CDN uptimes are 'poor' it should fall back with the answer that has the highest provider uptime (we will use our fetchCDN-functions).

Let's create our configuration object:

const configuration = {
    /** List of  providers configuration*/
    providers: [
        {
            name: ('jsdelivr-cdn' as TCDNProvider), // CDN Provider alias to work with
            monitorId: (301 as TMonitor), // The ID of the Monitor that is created by user to monitor hostname
            cname: 'www.foo.com' // cname to pick as a result
        },
        {
            name: ('cloudflare' as TCDNProvider),
            monitorId: (302 as TMonitor),
            cname: 'www.bar.com'
        },
        {
            name: ('google-cloud-cdn' as TCDNProvider),
            monitorId: (303 as TMonitor),
            cname: 'www.baz.com'
        }
    ],
    defaultTtl: 20, // The DNS TTL to be applied to DNS responses in seconds.
    availabilityThreshold: 90 // The Board value for providers to compare with
};

We took our Monitors IDs monitorId: (302 as TMonitor), from the PerfOps Panel Monitors Page and defined the availability threshold to 90 (percent).

Now, let's fill in our functions block with the set of functions that determine highest and lowest values for arrays and properties. Notice: that functions are pretty useful and can be added to other scripts if you use the configuration approach described above.

/**
 * Returns index of highest number in array
 */
const getHighest = (array: number[]): number => array.indexOf(Math.max(...array));
/**
 * Picks item which highest value in property
 */
const getHighestByProperty = <T>(array: T[], property):T => array[getHighest(array.map(item => item[property]))];
/**
 * Returns index of lowest number in array
 */
const getLowest = (array: number[]): number => array.indexOf(Math.min(...array));
/**
 * Picks item which lowest value in property
 */
const getLowestByProperty = <T>(array: T[], property):T => array[getLowest(array.map(item => item[property]))];

Let's parse the configuration and get all providers that have monitors online, we will use our isMonitorOnline function (more info at Custom Answers API):

    const { providers, defaultTtl, availabilityThreshold } = configuration;
    // Filter providers by monitor - check if the monitor is 'UP'
    const monitorFilteredProviders = providers.filter(
        (provider) => isMonitorOnline(provider.monitorId)
    );

Well... bad thing happened and all our monitors are down. We can't determine the best availabilities so let's simply return a random answer from our list:

    // If all monitors states are 'DOWN', choose random provider.
    if (monitorFilteredProviders.length === 0) {
        res.setCNAMERecord(providers[Math.floor(Math.random() * providers.length)].cname);
        res.setTTL(defaultTtl);
        return;
    }

If everything is fine and we have providers with working monitors - let's keep only those CDN providers that have availability more than 90 percent for the last hour:

    // Filter the previously obtained result. Choose providers that have 'UPTIME' value more that threshold.
    const availableFilteredProviders = monitorFilteredProviders.filter(
        (provider) => fetchCdnRumUptime(provider.name) > availabilityThreshold
    );

Everything is perfect, we have the list of CDN providers with good uptime, let's analyze their performance data and return the one with the lowest performance value for the last hour as the answer. Remember - the lower 'performance' value - the better - it represents value based on response time, so yes- we need the lowest one.

    // If the filtered results list is not empty
    if (availableFilteredProviders.length) {
        // Create array map with the performance data for each provider we have in the results list
        const perfProvidersData = availableFilteredProviders.map(
            (provider) => ({
                provider,
                perf: fetchCdnRumPerformance(provider.name)
            })
        );
        // Set the response TTL to the defaultTtl, select the provider with the best (lowest) performance value
        // and set the response Address to the cname associated with that provider
        res.setCNAMERecord(getLowestByProperty(perfProvidersData, 'perf').provider.cname);
        res.setTTL(defaultTtl);
        return;
    }

In case we have the CDN availability lower than our threshold - we simply return the answer with the best provider uptime as fallback:

// Fallback. Create the map with the availability (uptime data) for each provider from the original list
    const uptimeProvidersData = providers.map(
        (provider) => ({
            provider,
            uptime: fetchCdnRumUptime(provider.name)
        })
    );
    // Set the response TTL to the defaultTtl and the response Address to the cname
    // associated with the provider with the best uptime
    res.setCNAMERecord(getHighestByProperty(uptimeProvidersData, 'uptime').provider.cname);
    res.setTTL(defaultTtl);
    return;

That's it! Here is our final script code:

// Optimal Round Trip Time with Sonar Availability
// Main configuration
const configuration = {
    /** List of  providers configuration*/
    providers: [
        {
            name: ('jsdelivr-cdn' as TCDNProvider), // CDN Provider alias to work with
            monitorId: (301 as TMonitor), // The ID of the Monitor that is created by user to monitor hostname
            cname: 'www.foo.com' // cname to pick as a result
        },
        {
            name: ('cloudflare' as TCDNProvider),
            monitorId: (302 as TMonitor),
            cname: 'www.bar.com'
        },
        {
            name: ('google-cloud-cdn' as TCDNProvider),
            monitorId: (303 as TMonitor),
            cname: 'www.baz.com'
        }
    ],
    defaultTtl: 20, // The DNS TTL to be applied to DNS responses in seconds.
    availabilityThreshold: 90 // The Board value for providers to compare with
};
/**
 * Returns index of highest number in array
 */
const getHighest = (array: number[]): number => array.indexOf(Math.max(...array));
/**
 * Picks item which highest value in property
 */
const getHighestByProperty = <T>(array: T[], property):T => array[getHighest(array.map(item => item[property]))];
/**
 * Returns index of lowest number in array
 */
const getLowest = (array: number[]): number => array.indexOf(Math.min(...array));
/**
 * Picks item which lowest value in property
 */
const getLowestByProperty = <T>(array: T[], property):T => array[getLowest(array.map(item => item[property]))];

function onRequest(req: IRequest, res: IResponse) {
    const { providers, defaultTtl, availabilityThreshold } = configuration;
    // Filter providers by monitor - check if the monitor is 'UP'
    const monitorFilteredProviders = providers.filter(
        (provider) => isMonitorOnline(provider.monitorId)
    );
    // If all monitors states are 'DOWN', choose random provider.
    if (monitorFilteredProviders.length === 0) {
        res.setCNAMERecord(providers[Math.floor(Math.random() * providers.length)].cname);
        res.setTTL(defaultTtl);
        return;
    }
    // Filter the previously obtained result. Choose providers that have 'UPTIME' value more that threshold.
    const availableFilteredProviders = monitorFilteredProviders.filter(
        (provider) => fetchCdnRumUptime(provider.name) > availabilityThreshold
    );
    // If the filtered results list is not empty
    if (availableFilteredProviders.length) {
        // Create array map with the performance data for each provider we have in the results list
        const perfProvidersData = availableFilteredProviders.map(
            (provider) => ({
                provider,
                perf: fetchCdnRumPerformance(provider.name)
            })
        );
        // Set the response TTL to the defaultTtl, select the provider with the best (lowest) performance value
        // and set the response Address to the cname associated with that provider
        res.setCNAMERecord(getLowestByProperty(perfProvidersData, 'perf').provider.cname);
        res.setTTL(defaultTtl);
        return;
    }

    // Fallback. Create the map with the availability (uptime data) for each provider from the original list
    const uptimeProvidersData = providers.map(
        (provider) => ({
            provider,
            uptime: fetchCdnRumUptime(provider.name)
        })
    );
    // Set the response TTL to the defaultTtl and the response Address to the cname
    // associated with the provider with the best uptime
    res.setCNAMERecord(getHighestByProperty(uptimeProvidersData, 'uptime').provider.cname);
    res.setTTL(defaultTtl);
    return;
}