milergeo added
This commit is contained in:
@@ -149,12 +149,16 @@ func collectEligibleCandidates(nearby []redis.GeoLocation) ([]*milerCandidate, [
|
||||
continue
|
||||
}
|
||||
|
||||
// Only today's open stops count towards the cap. An order assigned
|
||||
// yesterday or last month and never closed (rider app not updated,
|
||||
// order abandoned) used to hold the rider at the cap forever, so the
|
||||
// one rider actually working was skipped for every new order.
|
||||
var activeCount int64
|
||||
db.DB.Model(&models.BookingAssignment{}).
|
||||
Where("mileruserid = ? AND assignmentstatus IN ?", milerUserID, []string{
|
||||
Where("mileruserid = ? AND assignmentstatus IN ? AND assignedat >= ?", milerUserID, []string{
|
||||
constants.AssignmentAssigned,
|
||||
constants.AssignmentAccepted,
|
||||
}).
|
||||
}, startOfISTDay(time.Now())).
|
||||
Count(&activeCount)
|
||||
|
||||
if activeCount >= maxActiveBookings() {
|
||||
@@ -185,6 +189,14 @@ func collectEligibleCandidates(nearby []redis.GeoLocation) ([]*milerCandidate, [
|
||||
return candidates, aiCandidates
|
||||
}
|
||||
|
||||
// startOfISTDay is midnight today in India, the boundary for "today's"
|
||||
// open stops. An absolute instant, so it compares correctly with assignedat
|
||||
// whether the column stores IST wall-clock or a real timestamp.
|
||||
func startOfISTDay(now time.Time) time.Time {
|
||||
n := now.In(utils.ISTLocation())
|
||||
return time.Date(n.Year(), n.Month(), n.Day(), 0, 0, 0, 0, utils.ISTLocation())
|
||||
}
|
||||
|
||||
// ─── Per-miler stats ─────────────────────────────────────────────────────────
|
||||
|
||||
func fetchMilerStats(milerUserID int) (onTimeRate float64, completedToday int64) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"doormile/constants"
|
||||
"doormile/db"
|
||||
"doormile/internal/cxstage"
|
||||
"doormile/internal/milergeo"
|
||||
"doormile/internal/routing"
|
||||
"doormile/models"
|
||||
"doormile/utils"
|
||||
@@ -196,22 +197,9 @@ func queryNearbyMilers(lat, lon float64) ([]redis.GeoLocation, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
locs, err := db.Rdb.GeoSearchLocation(ctx, "milers:locations", &redis.GeoSearchLocationQuery{
|
||||
GeoSearchQuery: redis.GeoSearchQuery{
|
||||
Longitude: lon,
|
||||
Latitude: lat,
|
||||
Radius: geoRadiusKm,
|
||||
RadiusUnit: "km",
|
||||
Sort: "ASC",
|
||||
Count: geoMaxCount,
|
||||
},
|
||||
WithDist: true,
|
||||
}).Result()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return locs, nil
|
||||
// milergeo falls back to GEORADIUS on Redis older than 6.2, where
|
||||
// GEOSEARCH does not exist and every order would find "no riders".
|
||||
return milergeo.Search(ctx, db.Rdb, lat, lon, geoRadiusKm, geoMaxCount)
|
||||
}
|
||||
|
||||
// commitAssignment writes the BookingAssignment row, updates the booking and the
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package assignment
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// The per-miler concurrent-stop cap.
|
||||
//
|
||||
@@ -30,3 +33,22 @@ func TestMaxActiveBookings(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The cap counts only stops assigned since midnight India time, so an order
|
||||
// left open yesterday or last month no longer blocks a working rider.
|
||||
func TestStartOfISTDay(t *testing.T) {
|
||||
ist := time.FixedZone("IST", 5*3600+30*60)
|
||||
cases := []struct{ now, want time.Time }{
|
||||
// 11:43 IST on 6 Oct -> 00:00 IST 6 Oct
|
||||
{time.Date(2026, 10, 6, 11, 43, 0, 0, ist), time.Date(2026, 10, 6, 0, 0, 0, 0, ist)},
|
||||
// 20:00 UTC on 5 Oct is already 01:30 on 6 Oct in India
|
||||
{time.Date(2026, 10, 5, 20, 0, 0, 0, time.UTC), time.Date(2026, 10, 6, 0, 0, 0, 0, ist)},
|
||||
// 18:29 UTC on 5 Oct is still 23:59 on 5 Oct in India
|
||||
{time.Date(2026, 10, 5, 18, 29, 0, 0, time.UTC), time.Date(2026, 10, 5, 0, 0, 0, 0, ist)},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := startOfISTDay(c.now); !got.Equal(c.want) {
|
||||
t.Errorf("startOfISTDay(%v) = %v, want %v", c.now, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user