feat: المجموعة H — المواقع في Redis، والقاعدة من الـworker فقط
كان كل نبضة موقع (كل 1-3 ثوانٍ لكل سائق متصل) تكلّف استعلاماً + كتابة صف السائق في Postgres — أثقل حمل كان على القاعدة، وأثقل حتى من سيرو. - H1/H2: نبضة الموقع = Redis فقط، بعتبات سيرو (10م / 1.0 سرعة / 5° اتجاه). سائق واقف = EXPIRE واحد: لا كتابة، لا نقطة مسار، ولا بثّ للراكب - H3: لقطة آخر موقع على drivers (heading/speed/loc_status/loc_updated_at) يكتبها الـworker دورياً. لم نُنشئ جدولاً منفصلاً — drivers أصلاً صف واحد لكل سائق - H4: driver_tracks — تتراكم في قائمة Redis ويُدرجها الـworker بعبارة واحدة - H5: فهرسا available/busy — البحث يمسح المتاحين فقط. السائق يصير busy عند القبول ويعود available عند الإنهاء/الإلغاء - H8: المطابقة والاحتيال و«الرحلات المتاحة» تقرأ الموقع الحيّ من Redis. كشف تزوير الوصول خاصةً يجب ألّا يحكم بلقطة دورية الـworker صار حقيقياً (كان setInterval فارغاً): سياق Nest مستقل، تفريغ كل 5s، قفل يمنع تراكب الدورات، وتفريغة أخيرة عند SIGTERM. مؤجَّل من H: H6 (سلوك السائق) و H7 (ساعات العمل) — تحليلات تُبنى من driver_tracks لاحقاً. هجرة: DriverLocations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a83dd7e5e5
commit
0ed3a3160a
@@ -57,20 +57,34 @@ export class RealtimeGateway implements OnGatewayConnection {
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
/** موقع السائق الحي: يحدّث Redis GEO ويبثّ لغرفة الرحلة. */
|
||||
/**
|
||||
* موقع السائق الحي: Redis فقط (لا قاعدة — docs/17 H1)، والبثّ لغرفة الرحلة
|
||||
* **فقط عند حركة ذات دلالة**؛ سائق واقف يرسل كل ثانية لا يُغرق الراكب
|
||||
* بتحديثات متطابقة.
|
||||
*/
|
||||
@SubscribeMessage('driver:location')
|
||||
async onDriverLocation(
|
||||
@ConnectedSocket() c: Socket,
|
||||
@MessageBody() body: { lat: number; lng: number; tripId?: string },
|
||||
@MessageBody()
|
||||
body: { lat: number; lng: number; heading?: number; speed?: number; tripId?: string },
|
||||
) {
|
||||
const u = c.data.user;
|
||||
if (!u || u.role !== 'driver' || body?.lat == null || body?.lng == null) return;
|
||||
await this.drivers.updateLocation(u.tenantId, u.userId, body.lat, body.lng);
|
||||
if (body.tripId) {
|
||||
|
||||
const { significant } = await this.drivers.updateLocation(
|
||||
u.tenantId,
|
||||
u.userId,
|
||||
body.lat,
|
||||
body.lng,
|
||||
{ heading: body.heading, speed: body.speed },
|
||||
);
|
||||
if (body.tripId && significant) {
|
||||
c.to(this.tripRoom(u.tenantId, body.tripId)).emit('driver:location', {
|
||||
tripId: body.tripId,
|
||||
lat: body.lat,
|
||||
lng: body.lng,
|
||||
heading: body.heading ?? 0,
|
||||
speed: body.speed ?? 0,
|
||||
});
|
||||
}
|
||||
return { ok: true };
|
||||
|
||||
Reference in New Issue
Block a user