prepare($sqlList); $stmt->execute(); $mikrotiks = $stmt->fetchAll(PDO::FETCH_ASSOC); $pdo = null; if (empty($mikrotiks)) { echo "[" . date('Y-m-d H:i:s') . "] Tidak ada data MikroTik.\n"; exit; } // MULTI PROCESS $child_pids = []; $outfiles = []; foreach ($mikrotiks as $data) { while (count($child_pids) >= $max_processes) { foreach ($child_pids as $key => $pid) { if (pcntl_waitpid($pid, $status, WNOHANG) > 0) { unset($child_pids[$key]); } } usleep(100000); } $safeId = preg_replace('~[^A-Za-z0-9_\-]~', '_', substr($data['board_id'], 0, 64)); $outfile = $tmpDir . "/mt_" . $safeId . "_" . microtime(true) . ".json"; $outfiles[] = $outfile; $pid = pcntl_fork(); if ($pid == -1) continue; if ($pid) { $child_pids[] = $pid; } else { process_mikrotik_child($data, $timeout_api, $outfile); exit; } } // tunggu selesai foreach ($child_pids as $pid) { pcntl_waitpid($pid, $status); } // UPDATE DB include "/www/wwwroot/bilspro/config/connect.php"; $pdo->exec("SET time_zone = '+07:00'"); $updated = 0; $failed = 0; try { $pdo->beginTransaction(); $sql = " UPDATE setting_mikrotik SET hsa = :hsa, last_time_check_ppp_hs = NOW() WHERE board_id = :id "; $stmt = $pdo->prepare($sql); foreach ($outfiles as $file) { if (!is_file($file)) continue; $row = json_decode(file_get_contents($file), true); @unlink($file); if (!$row || !isset($row['board_id'])) { $failed++; continue; } $stmt->execute([ ':hsa' => $row['hsa'] ?? '', ':id' => $row['board_id'], ]); $updated++; } $pdo->commit(); } catch (Exception $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } echo "ERROR: " . $e->getMessage() . "\n"; } echo "[" . date('Y-m-d H:i:s') . "] Selesai. Update: {$updated}, Fail: {$failed}\n"; // ================================ // CHILD PROCESS (PPPA & HSA FULL) // ================================ function process_mikrotik_child(array $data, int $timeout_api, string $outfile): void { $API = new RouterosAPI(); $API->timeout = $timeout_api; $result = [ 'board_id' => $data['board_id'], 'hsa' => '', ]; if ($API->connect2($data['ip_address'], $data['username'], $data['password'], $data['port_api'])) { // HOTSPOT $hotspot_active = []; $hotspot_users = $API->comm("/ip/hotspot/user/print"); if (is_array($hotspot_users)) { foreach ($hotspot_users as $item) { $user = $item['name'] ?? ''; $comment = $item['comment'] ?? ''; if ($user !== '' && strpos($comment, 'Login.') === 0) { $hotspot_active[] = "{$user}_" . substr($comment, 6); } } } $API->disconnect(); $result['hsa'] = implode('|', $hotspot_active); // HITUNG JUMLAH $hs_count = count($hotspot_active); // OUTPUT RAPI echo sprintf( "[%s] STATUS: OK | HS: %-5d | IP: %-15s | %s\n", date('Y-m-d H:i:s'), $hs_count, $data['ip_address'], $data['nama'] ?? '-' ); } else { echo sprintf( "[%s] STATUS: FAIL | IP: %-15s | %s\n", date('Y-m-d H:i:s'), $data['ip_address'], $data['nama'] ?? '-' ); } file_put_contents($outfile, json_encode($result, JSON_UNESCAPED_UNICODE)); }