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 pppa = :pppa, 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([ ':pppa' => $row['pppa'] ?? '', ':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'], 'pppa' => '', ]; if ($API->connect2($data['ip_address'], $data['username'], $data['password'], $data['port_api'])) { // PPPoE $pppoe_active = []; $pppoe_data = $API->comm("/ppp/active/print"); if (is_array($pppoe_data)) { foreach ($pppoe_data as $item) { $name = $item['name'] ?? ''; $addr = $item['address'] ?? ''; $mac = $item['caller-id'] ?? ''; if ($name !== '' && $addr !== '') { $pppoe_active[] = "{$name}_{$addr}_{$mac}"; } } } $API->disconnect(); $result['pppa'] = implode('|', $pppoe_active); // HITUNG JUMLAH $ppp_count = count($pppoe_active); // OUTPUT RAPI echo sprintf( "[%s] STATUS: OK | PPP: %-5d | IP: %-15s | %s\n", date('Y-m-d H:i:s'), $ppp_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)); }