fix: Allow passing timestamp

This commit is contained in:
js0ny 2025-12-06 02:44:03 +00:00
parent 8e462fedc1
commit 3509c556a1
5 changed files with 40 additions and 3 deletions

View file

@ -56,8 +56,6 @@ func (s *Server) snapshotHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
// Optimized query using window function (requires SQLite 3.25+) or standard group by max
// Using correlated subquery which is standard and works well with the index
query := ` query := `
SELECT drone_id, latitude, longitude, timestamp SELECT drone_id, latitude, longitude, timestamp
FROM drone_events t1 FROM drone_events t1

View file

@ -37,6 +37,7 @@
go go
bun bun
svelte-language-server svelte-language-server
typescript-language-server
]; ];
shellHook = '' shellHook = ''
export JAVA_HOME=${pkgs.jdk21} export JAVA_HOME=${pkgs.jdk21}

View file

@ -2,6 +2,7 @@ package io.github.js0ny.ilp_coursework.data.common;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Map;
import io.github.js0ny.ilp_coursework.data.response.DeliveryPathResponse; import io.github.js0ny.ilp_coursework.data.response.DeliveryPathResponse;
@ -62,4 +63,27 @@ public record DroneEvent(
} }
return events; return events;
} }
public static List<DroneEvent> fromPathResponseWithTimestamps(
DeliveryPathResponse resp, Map<Integer, LocalDateTime> deliveryTimestamps) {
List<DroneEvent> events = new java.util.ArrayList<>();
for (var p : resp.dronePaths()) {
String id = String.valueOf(p.droneId());
for (var d : p.deliveries()) {
LocalDateTime timestamp = deliveryTimestamps.get(d.deliveryId());
// Fallback to current time if the delivery does not carry a timestamp.
System.out.println("Generated event for drone " + id + " at " + timestamp.toString());
LocalDateTime current = timestamp != null ? timestamp : LocalDateTime.now();
for (var coord : d.flightPath()) {
events.add(new DroneEvent(
id,
coord.lat(),
coord.lng(),
current.toString()));
current = current.plusSeconds(1);
}
}
}
return events;
}
} }

View file

@ -31,6 +31,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.time.LocalDateTime;
/** /**
* Class that handles calculations about deliverypath * Class that handles calculations about deliverypath
@ -126,6 +127,7 @@ public class PathFinderService {
return new DeliveryPathResponse(0f, 0, new DronePath[0]); return new DeliveryPathResponse(0f, 0, new DronePath[0]);
} }
Map<Integer, LocalDateTime> deliveryTimestamps = new HashMap<>();
for (var r : records) { for (var r : records) {
if (isRestricted(r.delivery())) { if (isRestricted(r.delivery())) {
throw new IllegalStateException( throw new IllegalStateException(
@ -133,6 +135,9 @@ public class PathFinderService {
+ r.id() + r.id()
+ " is located within a restricted area and cannot be fulfilled"); + " is located within a restricted area and cannot be fulfilled");
} }
if (r.date() != null && r.time() != null) {
deliveryTimestamps.put(r.id(), LocalDateTime.of(r.date(), r.time()));
}
} }
Map<String, List<MedDispatchRecRequest>> assigned = assignDeliveries(records); Map<String, List<MedDispatchRecRequest>> assigned = assignDeliveries(records);
@ -177,7 +182,7 @@ public class PathFinderService {
var resp = new DeliveryPathResponse(totalCost, totalMoves, paths.toArray(new DronePath[0])); var resp = new DeliveryPathResponse(totalCost, totalMoves, paths.toArray(new DronePath[0]));
telemetryService.sendEventAsyncByPathResponse(resp); telemetryService.sendEventAsyncByPathResponse(resp, deliveryTimestamps);
return resp; return resp;
} }

View file

@ -4,6 +4,7 @@ import java.net.http.HttpClient;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.Map;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -40,6 +41,14 @@ public class TelemetryService {
} }
} }
public void sendEventAsyncByPathResponse(DeliveryPathResponse resp,
Map<Integer, LocalDateTime> deliveryTimestamps) {
var events = DroneEvent.fromPathResponseWithTimestamps(resp, deliveryTimestamps);
for (var event : events) {
sendEventAsync(event);
}
}
public void sendEventAsync(DroneEvent event) { public void sendEventAsync(DroneEvent event) {
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
try { try {