0)'; } // Get total/online/in-use $known = Database::queryKeyValueList("SELECT locationid, Count(*) AS val FROM machine m $join WHERE m.lastseen > $cutoff $where GROUP BY locationid"); $on = Database::queryKeyValueList("SELECT locationid, Count(*) AS val FROM machine m $join WHERE m.state IN ('IDLE', 'OCCUPIED') $where GROUP BY locationid"); $used = Database::queryKeyValueList("SELECT locationid, Count(*) AS val FROM machine m $join WHERE m.state = 'OCCUPIED' $where GROUP BY locationid"); // Get calendar data if available if (Module::isAvailable('locationinfo')) { // Refresh all calendars around 07:00 $calendars = LocationInfo::getAllCalendars(date('G') != 7 || date('i') >= 10); } // Mash together $data = ['usage' => []]; foreach ($known as $lid => $val) { $entry = ['t' => $val]; if (isset($on[$lid])) { $entry['o'] = $on[$lid]; } if (isset($used[$lid])) { $entry['u'] = $used[$lid]; } if (isset($calendars[$lid])) { $title = LocationInfo::extractCurrentEvent($calendars[$lid]); if (!empty($title)) { $entry['event'] = $title; } } $data['usage'][$lid] = $entry; } Database::exec("INSERT INTO statistic (dateline, typeid, clientip, username, data) VALUES (:now, '~stats', '', '', :vals)", array( 'now' => $NOW, 'vals' => json_encode($data), )); } function state_cleanup() { // Fix online state of machines that crashed $standby = time() - 86400 * 4; // Reset standby machines after four days $on = time() - 610; // Reset others after ~10 minutes // Query for logging $res = Database::simpleQuery("SELECT machineuuid, clientip, state, logintime, lastseen, live_memfree, live_swapfree, live_tmpfree FROM machine WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'"); foreach ($res as $row) { ClientLog::write($row, 'machine-mismatch-cron', 'Client timed out, last known state is ' . $row['state'] . '. Free RAM: ' . Util::readableFileSize($row['live_memfree'], -1, 2) . ', free Swap: ' . Util::readableFileSize($row['live_swapfree'], -1, 2) . ', free ID44: ' . Util::readableFileSize($row['live_tmpfree'], -1, 2)); if ($row['state'] === 'OCCUPIED') { $length = $row['lastseen'] - $row['logintime']; if ($length > 0 && $length < 86400 * 7) { Statistics::logMachineState($row['machineuuid'], $row['clientip'], Statistics::SESSION_LENGTH, $row['logintime'], $length); } } elseif ($row['state'] === 'STANDBY') { $length = time() - $row['lastseen']; if ($length > 0 && $length < 86400 * 7) { Statistics::logMachineState($row['machineuuid'], $row['clientip'], Statistics::SUSPEND_LENGTH, $row['lastseen'], $length); } } } // Update -- yes this is not atomic. Should be sufficient for simple warnings and bookkeeping though. Database::exec("UPDATE machine SET logintime = 0, state = 'OFFLINE' WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'"); } state_cleanup(); logstats(); if (mt_rand(1, 10) === 1) { Database::exec("DELETE FROM statistic WHERE (UNIX_TIMESTAMP() - 86400 * 365 * 2) > dateline"); if (mt_rand(1, 100) === 1) { Database::exec("OPTIMIZE TABLE statistic"); } } if (mt_rand(1, 10) === 1) { Database::exec("DELETE FROM machine WHERE (UNIX_TIMESTAMP() - 86400 * 365 * 2) > lastseen"); if (mt_rand(1, 100) === 1) { Database::exec("OPTIMIZE TABLE machine"); } }