<commit_before>

var restify = require('restify');
var url = require('url');
var _ = require('underscore');
var async = require('async');
const qs = require('querystring');
const got = require('got');

function configureServer (opts, ctx) {
  var server = restify.createServer(opts);
  var consul = ctx.consul;


  function get_candidates (service, next) {
    return consul.catalog.service.nodes({service: service}, next);
  }

  function apply_policies (services) {
    function byTotalActive (x) { return x.HealthStatus.total.active; }
    function hasHealth (x) { return x && x.HealthStatus; }
    return _.sortBy(services.filter(hasHealth), byTotalActive);
  }

  function require_health (services, next) {
    async.each(services, get_health, function finish (err) {
      next(err, services);
    });
  }

  function fetch_services (service, tenants, next) {
    if (tenants.call) {
      next = tenants;
      tenants = [ ];
    }
    return get_candidates(service, function (err, clusters) {
      function filter_runners (tenant) {
        var runners = _.where(clusters, { ServiceAddress : tenant.ServiceAddress });
        return runners;
      }
      var orig_len = clusters.length;
      if (1 == tenants.length) {
        clusters = filter_runners(tenants[0]);
        console.log('tenants', tenants.length, 'orig', orig_len, 'filtered', clusters.length);
        return next(err, clusters);
      } else if (tenants.length > 1) {
        clusters = _.flatten(_.map(tenants, filter_runners));
        console.log('tenants', tenants.length, 'orig', orig_len, 'filtered', clusters.length);
        return next(err, clusters);
      }
      return require_health(clusters, next);
    });
  }

  function fetch_elected_services (service, tenants, next) {
    if (tenants.call) {
      next = tenants;
      tenants = [ ];
    }
    return fetch_services(service, tenants, function (err, services) {
      if (err) throw err;
      if (tenants.length > 0) {
        return next(services);
      }
      return next(apply_policies(services));
    });
  }

  function get_best_service (service, next) {
    return fetch_elected_services(service, function (services) {
      // if (err) throw err;
      return next(elect(services));
    });
  }

  function elect (services) {
    return services[0];
  }

  function suggest (elected) {
    var candidate = { };
    _.extend(candidate, elected);
    return candidate;
  }

  function ratify (elected, next) {
  }

  function get_health (runner, done) {
    var uri = url.format({ hostname: runner.ServiceAddress, port: runner.ServicePort, pathname: '/stats/active', protocol: 'http' });
    console.log("fetching", uri);
    got(uri).json( ).then(function (body) {
      runner.HealthStatus = body;
      done( );
    }).catch(function (err) {
      console.log("ERROR skipping", arguments);
      done( );
    });
  }


  server.use(function (req, res, next) {
    res.locals = { };
    next( );
  });

  function format_locals (req, res, next) {
    res.send(res.locals);
    next( );
  }

  server.get('/suggested/consul/:service', function (req, res, next) {
  });
  server.get('/available/consul/:service', function (req, res, next) {
    fetch_services(req.params.service, function (err, services) {
      res.locals.services = services;
      next( );
    });
  }, format_locals);

  server.get('/elected/consul/:service', function (req, res, next) {
    get_best_service(req.params.service, function (clusters) {
      res.locals.service = clusters;
      console.log('BEST SERVICE', clusters);
      next( );
    })
  },
  format_locals
  );

  server.get('/scheduled/consul/:service/:tenant/:suffix',
  function (req, res, next) {
    var suffix = req.params.suffix || 'backends';
    var domain = [ req.params.tenant, suffix ].join('.');
    var search  = {service: suffix, tag: req.params.tenant };
    console.log('SEARCH TENANT', search);
    consul.catalog.service.nodes(search, function (err, tenants) {
      if (err) {
        console.log(err);
        return next(err);
      }

      var orig_num_tenants = tenants ? tenants.length : 0;
      tenants = _.uniq(tenants, _.iteratee('ServiceAddress'));
      console.log("SEARCH TENANT RESULTS", err, orig_num_tenants, tenants ? tenants.length : err);

      res.locals.tenants = tenants;
      next( );

    });
  },
  function (req, res, next) {
    var search = {service: req.params.service };
    if (res.locals.tenants.length >= 1) {
      // res.locals.services = res.locals.tenants;
      // res.locals.preferred = res.locals.tenants[0];
      // console.log("skipping CLUSTER search", res.locals.tenants.length);
      // next( );
      // return;
    }
    fetch_elected_services(req.params.service, res.locals.tenants, function (services) {
      console.log("SEARCH CLUSTER RESULTS", services.length);
      res.locals.services = services;
      res.locals.preferred = elect(services);
      next( );
    });
  },
  function (req, res, next) {
    var tenants = res.locals.tenants;
    function hostsTenant  ( ) { }
    function electRunners (tenant) {
      var runners = _.where(res.locals.services, { ServiceAddress : tenant.ServiceAddress });
      return runners;
    }
    var candidates = _.flatten(_.map(tenants, electRunners));
    console.log("candidates", candidates.length);
    res.locals.candidates = candidates;
    next( );
  },
  function (req, res, next) {
    if (_.isEmpty(res.locals.candidates)) {
      // this is a new/non-existing tenant
      res.locals.elected = res.locals.preferred;
    } else {
      //pre-existing, use a candidate
      res.locals.elected = res.locals.candidates[0];
    }
    var urlish = { hostname: res.locals.elected.ServiceAddress
    , port: res.locals.elected.ServicePort
    , pathname: '/environs/' + req.params.tenant
    , protocol: 'http'
    };
    var uri = url.format(urlish);
    console.log('elected', uri);
    res.locals.endpoint = uri;
    res.header('X-ELECTED-RUNNER', uri);
    next( );
  },
  format_locals
  );

  server.get('/consul/:service', function (req, res, next) {
    consul.catalog.service.nodes({service: req.params.service}, function (err, clusters) {
      res.locals.services = clusters;
      next( );
    });
  },
  function (req, res, next) {
    async.each(res.locals.services, get_health, function finish ( ) {
      res.locals.services = _.sortBy(res.locals.services.filter(function (x) { return x && x.HealthStatus; }), function (x) { return x.HealthStatus.total.active; });
      next( );
    });
  },
  function (req, res, next) {<commit_msg>keep demuxers alive<commit_after>

var restify = require('restify');
var url = require('url');
var _ = require('underscore');
var async = require('async');
const qs = require('querystring');
const got = require('got');

function configureServer (opts, ctx) {
  var server = restify.createServer(opts);
  var consul = ctx.consul;


  function get_candidates (service, next) {
    return consul.catalog.service.nodes({service: service}, next);
  }

  function apply_policies (services) {
    function byTotalActive (x) { return x.HealthStatus.total.active; }
    function hasHealth (x) { return x && x.HealthStatus; }
    return _.sortBy(services.filter(hasHealth), byTotalActive);
  }

  function require_health (services, next) {
    async.each(services, get_health, function finish (err) {
      next(err, services);
    });
  }

  function fetch_services (service, tenants, next) {
    if (tenants.call) {
      next = tenants;
      tenants = [ ];
    }
    return get_candidates(service, function (err, clusters) {
      function filter_runners (tenant) {
        var runners = _.where(clusters, { ServiceAddress : tenant.ServiceAddress });
        return runners;
      }
      var orig_len = clusters.length;
      if (1 == tenants.length) {
        clusters = filter_runners(tenants[0]);
        console.log('tenants', tenants.length, 'orig', orig_len, 'filtered', clusters.length);
        return next(err, clusters);
      } else if (tenants.length > 1) {
        clusters = _.flatten(_.map(tenants, filter_runners));
        console.log('tenants', tenants.length, 'orig', orig_len, 'filtered', clusters.length);
        return next(err, clusters);
      }
      return require_health(clusters, next);
    });
  }

  function fetch_elected_services (service, tenants, next) {
    if (tenants.call) {
      next = tenants;
      tenants = [ ];
    }
    return fetch_services(service, tenants, function (err, services) {
      if (err) throw err;
      if (tenants.length > 0) {
        return next(services);
      }
      return next(apply_policies(services));
    });
  }

  function get_best_service (service, next) {
    return fetch_elected_services(service, function (services) {
      // if (err) throw err;
      return next(elect(services));
    });
  }

  function elect (services) {
    return services[0];
  }

  function suggest (elected) {
    var candidate = { };
    _.extend(candidate, elected);
    return candidate;
  }

  function ratify (elected, next) {
  }

  function get_health (runner, done) {
    var uri = url.format({ hostname: runner.ServiceAddress, port: runner.ServicePort, pathname: '/stats/active', protocol: 'http' });
    console.log("fetching", uri);
    got(uri).json( ).then(function (body) {
      runner.HealthStatus = body;
      done( );
    }).catch(function (err) {
      console.log("ERROR skipping", arguments);
      done( );
    });
  }


  server.use(function (req, res, next) {
    res.locals = { };
    next( );
  });

  function format_locals (req, res, next) {
    res.send(res.locals);
    next( );
  }

  server.get('/suggested/consul/:service', function (req, res, next) {
  });
  server.get('/available/consul/:service', function (req, res, next) {
    fetch_services(req.params.service, function (err, services) {
      res.locals.services = services;
      next( );
    });
  }, format_locals);

  server.get('/elected/consul/:service', function (req, res, next) {
    get_best_service(req.params.service, function (clusters) {
      res.locals.service = clusters;
      console.log('BEST SERVICE', clusters);
      next( );
    })
  },
  format_locals
  );

  server.get('/scheduled/consul/:service/:tenant/:suffix',
  function (req, res, next) {
    var suffix = req.params.suffix || 'backends';
    var domain = [ req.params.tenant, suffix ].join('.');
    var search  = {service: suffix, tag: req.params.tenant };
    console.log('SEARCH TENANT', search);
    consul.catalog.service.nodes(search, function (err, tenants) {
      if (err) {
        console.log(err);
        return next(err);
      }

      var orig_num_tenants = tenants ? tenants.length : 0;
      tenants = _.uniq(tenants, _.iteratee('ServiceAddress'));
      console.log("SEARCH TENANT RESULTS", err, orig_num_tenants, tenants ? tenants.length : err);

      res.locals.tenants = tenants;
      next( );

    });
  },
  function (req, res, next) {
    var search = {service: req.params.service };
    if (res.locals.tenants.length >= 1) {
      // res.locals.services = res.locals.tenants;
      // res.locals.preferred = res.locals.tenants[0];
      // console.log("skipping CLUSTER search", res.locals.tenants.length);
      // next( );
      // return;
    }
    fetch_elected_services(req.params.service, res.locals.tenants, function (services) {
      console.log("SEARCH CLUSTER RESULTS", services.length);
      res.locals.services = services;
      res.locals.preferred = elect(services);
      next( );
    });
  },
  function (req, res, next) {
    var tenants = res.locals.tenants;
    function hostsTenant  ( ) { }
    function electRunners (tenant) {
      var runners = _.where(res.locals.services, { ServiceAddress : tenant.ServiceAddress });
      return runners;
    }
    var candidates = _.flatten(_.map(tenants, electRunners));
    console.log("candidates", candidates.length);
    res.locals.candidates = candidates;
    next( );
  },
  function (req, res, next) {
    if (_.isEmpty(res.locals.candidates)) {
      // this is a new/non-existing tenant
      res.locals.elected = res.locals.preferred;
    } else {
      //pre-existing, use a candidate
      res.locals.elected = res.locals.candidates[0];
    }
    if (!res.locals.elected) {
      var fail = { tenant: res.locals.tenants[0], candidates: res.locals.candidates };
      console.log("FAILED TENANT", fail.tenant);
      console.log("FAIL NO SUITABLE CANDIDATE", fail);
      res.send(404, fail);
      return next(fail);
    }
    var urlish = { hostname: res.locals.elected.ServiceAddress
    , port: res.locals.elected.ServicePort
    , pathname: '/environs/' + req.params.tenant
    , protocol: 'http'
    };
    var uri = url.format(urlish);
    console.log('elected', uri);
    res.locals.endpoint = uri;
    res.header('X-ELECTED-RUNNER', uri);
    next( );
  },
  format_locals
  );

  server.get('/consul/:service', function (req, res, next) {
    consul.catalog.service.nodes({service: req.params.service}, function (err, clusters) {
      res.locals.services = clusters;
      next( );
    });
  },
  function (req, res, next) {
    async.each(res.locals.services, get_health, function finish ( ) {
      res.locals.services = _.sortBy(res.locals.services.filter(function (x) { return x && x.HealthStatus; }), function (x) { return x.HealthStatus.total.active; });
      next( );
    });
  },
  function (req, res, next) {
{'fraction_non_alphanumeric': 0.14865267232395415, 'fraction_numerical': 0.001637635849337502, 'mean_word_length': 2.953796350794585, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '900897', 'n_tokens_mistral': 4362, 'n_tokens_neox': 4253, 'n_words': 922}