Update: 2026-07-09 03:41:48
This commit is contained in:
@@ -1,53 +1,85 @@
|
||||
<?php
|
||||
// cron_cleanup_waiting.php
|
||||
// مسار الاتصال بقاعدة البيانات
|
||||
require_once __DIR__ . '/../../get_connect.php';
|
||||
// cron_ride_timeout.php
|
||||
// 🔥 أُعيدت كتابته بالكامل: كان يعتمد على جدول waitingRides الذي لم يعد
|
||||
// يُملأ من تدفق add_ride.php الحقيقي (addWaitingRide.php لا يُستدعى من هناك)،
|
||||
// فكانت الرحلات العالقة بحالة 'waiting' لا تُصفَّر أبداً. الآن يعمل مباشرة
|
||||
// على جدول ride باستخدام أعمدة date/time المكتوبة فعلياً عند الإنشاء.
|
||||
|
||||
require_once __DIR__ . '/../../core/bootstrap.php';
|
||||
require_once __DIR__ . '/../../functions.php';
|
||||
|
||||
// تسجيل في اللوج لبداية العملية
|
||||
error_log("⏰ [Cleanup Cron] Started cleaning old waiting rides...");
|
||||
|
||||
$minutesLimit = 15;
|
||||
|
||||
try {
|
||||
// المدة المسموحة بالدقائق
|
||||
$minutesLimit = 15;
|
||||
$con = Database::get('main');
|
||||
|
||||
// =========================================================
|
||||
// الخطوة 1: تحديث الحالة في الجدول الرئيسي (الأرشيف)
|
||||
// الخطوة 1: جلب الرحلات العالقة (status='waiting' منذ أكثر من 15 دقيقة)
|
||||
// =========================================================
|
||||
// نقوم بتحديث حالة الرحلات التي ستُحذف ليعلم الراكب أنها انتهت (Time Out)
|
||||
// بدلاً من أن تبقى 'waiting' للأبد في سجلات الراكب
|
||||
|
||||
$sqlUpdate = "UPDATE ride
|
||||
SET status = 'timeout'
|
||||
WHERE id IN (
|
||||
SELECT id FROM waitingRides
|
||||
WHERE created_at < DATE_SUB(NOW(), INTERVAL $minutesLimit MINUTE)
|
||||
) AND status = 'waiting'"; // نتأكد أننا نحدث ما هو معلق فقط
|
||||
$sqlSelect = "SELECT id, passenger_id FROM ride
|
||||
WHERE status = 'waiting'
|
||||
AND TIMESTAMP(`date`, `time`) < DATE_SUB(NOW(), INTERVAL $minutesLimit MINUTE)";
|
||||
$stmtSelect = $con->prepare($sqlSelect);
|
||||
$stmtSelect->execute();
|
||||
$staleRides = $stmtSelect->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$stmtUpdate = $con->prepare($sqlUpdate);
|
||||
$stmtUpdate->execute();
|
||||
$updatedCount = $stmtUpdate->rowCount();
|
||||
$updatedCount = 0;
|
||||
|
||||
if (!empty($staleRides)) {
|
||||
$sqlUpdate = "UPDATE ride SET status = 'timeout', updated_at = NOW() WHERE id = ? AND status = 'waiting'";
|
||||
$stmtUpdate = $con->prepare($sqlUpdate);
|
||||
|
||||
// نسخة أرشيفية (best-effort)
|
||||
$con_ride = null;
|
||||
try {
|
||||
$con_ride = Database::get('ride');
|
||||
} catch (Exception $e) {
|
||||
error_log("[cron_ride_timeout] Secondary ride DB unavailable: " . $e->getMessage());
|
||||
}
|
||||
$stmtUpdate2 = $con_ride ? $con_ride->prepare(
|
||||
"UPDATE ride SET status = 'timeout', updated_at = NOW() WHERE id = ? AND status = 'waiting'"
|
||||
) : null;
|
||||
|
||||
foreach ($staleRides as $ride) {
|
||||
$rideId = $ride['id'];
|
||||
|
||||
$stmtUpdate->execute([$rideId]);
|
||||
$updatedCount += $stmtUpdate->rowCount();
|
||||
|
||||
if ($stmtUpdate2) {
|
||||
try {
|
||||
$stmtUpdate2->execute([$rideId]);
|
||||
} catch (PDOException $e) {
|
||||
error_log("[cron_ride_timeout] Secondary DB update failed for #$rideId: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 🆕 تنظيف Redis + إعلام أي سائقين ما زالوا يرون هذا الطلب على أنه ملغى
|
||||
sendToLocationServer('cancel_ride', [
|
||||
'ride_id' => $rideId,
|
||||
'driver_id' => 0,
|
||||
'reason' => 'timeout',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// الخطوة 2: الحذف من جدول الانتظار (تنظيف Hot Data)
|
||||
// الخطوة 2: تنظيف جدول waitingRides القديم (إن وُجدت صفوف فيه من مسار قديم)
|
||||
// =========================================================
|
||||
|
||||
$sqlDelete = "DELETE FROM waitingRides
|
||||
WHERE created_at < DATE_SUB(NOW(), INTERVAL $minutesLimit MINUTE)";
|
||||
$deletedCount = 0;
|
||||
try {
|
||||
$sqlDelete = "DELETE FROM waitingRides WHERE created_at < DATE_SUB(NOW(), INTERVAL $minutesLimit MINUTE)";
|
||||
$stmtDelete = $con->prepare($sqlDelete);
|
||||
$stmtDelete->execute();
|
||||
$deletedCount = $stmtDelete->rowCount();
|
||||
} catch (PDOException $e) {
|
||||
error_log("[cron_ride_timeout] waitingRides cleanup skipped: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$stmtDelete = $con->prepare($sqlDelete);
|
||||
$stmtDelete->execute();
|
||||
$deletedCount = $stmtDelete->rowCount();
|
||||
|
||||
// =========================================================
|
||||
// الخطوة 3: (اختياري) تنظيف الريدز
|
||||
// =========================================================
|
||||
// بما أنك تستخدم Redis، المفترض أن تحذفها منه أيضاً.
|
||||
// لكن بما أن الريدز يعتمد على TTL (Expire) أو سيتم تحديثه عند الطلب القادم،
|
||||
// فالحذف من الـ MySQL يكفي لأن getRideWaiting سيفحص MySQL ولن يجدها.
|
||||
|
||||
// تقرير العملية
|
||||
if ($deletedCount > 0) {
|
||||
$msg = "✅ [Cleanup Cron] Success: Timed out $updatedCount rides in Main DB, and Deleted $deletedCount rides from Waiting DB.";
|
||||
if ($updatedCount > 0 || $deletedCount > 0) {
|
||||
$msg = "✅ [Cleanup Cron] Success: Timed out $updatedCount ride(s) in ride table, and cleaned $deletedCount legacy waitingRides row(s).";
|
||||
error_log($msg);
|
||||
echo json_encode(["status" => "success", "message" => $msg]);
|
||||
} else {
|
||||
@@ -59,7 +91,6 @@ try {
|
||||
} catch (PDOException $e) {
|
||||
$errorMsg = "❌ [Cleanup Cron] Error: " . $e->getMessage();
|
||||
error_log($errorMsg);
|
||||
error_log("[cron_ride_timeout] Error: " . $e->getMessage());
|
||||
echo json_encode(["status" => "failure", "message" => "An internal error occurred."]);
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user