function parse_monitor2_response()

in web_ui/src/applications/bistro/request_utils.php [4:75]


function parse_monitor2_response($request, $hp, $raw_response_str) {
  $keys = array_keys(array_diff_key($request, array('prefs' => 1)));
  $bad_keys = $keys;
  $response = array();
  // XXX make these available to InstanceHealthChecker
  $error_texts = array();

  // json_decode() can only handle UTF-8, while the server can potentially
  // send us non-UTF-8 JSON blob.  Yes, it's a thing.  No, the JSON spec
  // doesn't matter.  Mr. Crockford -- when can I use trailing commas?
  $response_str = iconv('latin1', 'utf-8', $raw_response_str);
  if ($response_str === false) {  // Should never happen? Probably?
    $error_texts[] = 'Could not convert response from latin1 to UTF-8: "'.
      strval($raw_response_str).'"';
  } else {
    $raw_response = json_decode($response_str, /* assoc = */ true);
    if (!is_array($raw_response)) {
      $error_texts[] = 'Invalid JSON in response: "'.strval($response_str).'"';
    } else {
      // TODO(lo-pri): consider checking for keys that weren't requested?
      $bad_keys = array();
      $error_texts = array();
      foreach ($keys as $key) {
        $value = idx($raw_response, $key, array());
        $error = idx($value, 'error');
        $data = idx($value, 'data');

        // Fake a 'running_tasks' handler using 'runtimes'
        // TODO: Delete once all Bistro deployments have running_tasks
        if ($error !== null && $key === 'running_tasks') {
          $value = idx($raw_response, 'runtimes', array());
          $error = idx($value, 'error');
          $data = idx($value, 'data');
          if ($data !== null) {
            $cur_time = time();
            $new_data = array();
            foreach ($data as $job => $node_runtime) {
              foreach ($node_runtime as $node => $runtime) {
                $new_data[$job][$node] = array(
                  'start_time' => $cur_time - $runtime);
              }
            }
            $data = $new_data;
          }
        }

        if (!is_array($value) || !$value ||
            $data === null || $error !== null) {
          $bad_keys[] = $key;
        }
        if ($error !== null) {
          $error_texts[] = $key.': '.$error;
        }
        if ($data !== null) {
          $response[$key] = $data;
        }
      }
    }
  }

  if ($bad_keys) {
    bistro_monitor_log()->error(
      'Hostport '.$hp.' returned no, partial, or bad data for '.
      implode(', ', $bad_keys).'. That is a bug. The displayed '.
      'results are incomplete.',
      $error_texts
        ? "Error texts:\n\n".implode("\n\n", $error_texts)
        : null);
  }

  return array($response, array_keys($response) == $keys);
}