diff --git a/app/Commands/NaverWorker.php b/app/Commands/NaverWorker.php index 83604af..9573240 100644 --- a/app/Commands/NaverWorker.php +++ b/app/Commands/NaverWorker.php @@ -40,22 +40,6 @@ class NaverWorker extends BaseCommand while (true) { - // 1. DB 연결 상태 체크 - try { - // 연결이 없으면 재연결 시도 - if ($this->db->connID === false) { - $this->db->reconnect(); - CLI::write(CLI::color('🔄 Database reconnected.', 'yellow')); - } - } catch (\Throwable $e) { - // 어떤 이유로든 에러 발생 시 재연결 시도 - try { - $this->db->reconnect(); - } catch (\Throwable $reconnectError) { - CLI::write(CLI::color('❌ Database reconnect failed: ' . $reconnectError->getMessage(), 'red')); - } - } - $result = $redis->brPop(['naver:raw_queue'], 30); if (!$result) { @@ -66,11 +50,30 @@ class NaverWorker extends BaseCommand if ($result) { $rawData = $result[1]; - // [1] 꺼내자마자 DB에 원문 저장 (2차 임시 저장) - $logId = $logModel->insert([ - 'raw_payload' => $rawData, - 'status' => 'INIT' - ]); + + // [1] 꺼내자마자 DB에 원문 저장 (2차 임시 저장) - 실패 시 재시도 + try { + $logId = $logModel->insert([ + 'raw_payload' => $rawData, + 'status' => 'INIT' + ]); + } catch (\CodeIgniter\Database\Exceptions\DatabaseException $e) { + // MySQL gone away 에러 시 재연결 후 재시도 + if (strpos($e->getMessage(), 'MySQL server has gone away') !== false) { + CLI::write(CLI::color('⚠️ MySQL gone away, reconnecting...', 'yellow')); + $this->db->close(); + $this->db = \Config\Database::connect(); + $logModel = model(NaverWorkerLogModel::class); + + // 재시도 + $logId = $logModel->insert([ + 'raw_payload' => $rawData, + 'status' => 'INIT' + ]); + } else { + throw $e; // 다른 에러면 그대로 throw + } + } try { $responseJson = json_decode($result[1], true); @@ -83,8 +86,8 @@ class NaverWorker extends BaseCommand // 서비스의 함수 하나로 모든 처리 완료 $insertId = $naverService->processArticle($payload); - // [3] 성공 시 로그 업데이트 - $logModel->update($logId, [ + // [3] 성공 시 로그 업데이트 (재연결 처리 포함) + $this->safeUpdateLog($logModel, $logId, [ 'atcl_no' => $payload['articleNumber'] ?? null, 'status' => 'SUCCESS', 'target_db_id' => $insertId @@ -95,8 +98,11 @@ class NaverWorker extends BaseCommand } catch (\Exception $e) { CLI::error("❌ Task Failed: " . $e->getMessage()); // 실패 로그는 여기서 남김 - // 1. DB 상태를 FAIL로 업데이트 (필수) - $logModel->update($logId, ['status' => 'FAIL', 'error_msg' => $e->getMessage()]); + // 1. DB 상태를 FAIL로 업데이트 (필수) (재연결 처리 포함) + $this->safeUpdateLog($logModel, $logId, [ + 'status' => 'FAIL', + 'error_msg' => $e->getMessage() + ]); // 2. Redis 실패 큐에 백업 (선택 - 나중에 모아서 다시 던질 때 편함) $redis->lPush('naver:failed_queue', $rawData); @@ -110,5 +116,27 @@ class NaverWorker extends BaseCommand } } + /** + * MySQL gone away 에러 발생 시 재연결 후 재시도하는 안전한 update + */ + protected function safeUpdateLog($logModel, $logId, $data) + { + try { + return $logModel->update($logId, $data); + } catch (\CodeIgniter\Database\Exceptions\DatabaseException $e) { + if (strpos($e->getMessage(), 'MySQL server has gone away') !== false) { + CLI::write(CLI::color('⚠️ MySQL gone away on update, reconnecting...', 'yellow')); + $this->db->close(); + $this->db = \Config\Database::connect(); + $logModel = model(\App\Models\Entities\NaverWorkerLogModel::class); + + // 재시도 + return $logModel->update($logId, $data); + } else { + throw $e; + } + } + } + } \ No newline at end of file