--- /dev/null
+package org.simantics.district.route;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.simantics.ObjectIdentitySchedulingRule;
+import org.simantics.db.Resource;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.district.route.internal.Activator;
+import org.simantics.district.route.internal.RoutePersistence;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 6.09
+ */
+public class RouteJob extends Job {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(RouteJob.class);
+
+ private RouterConfiguration config;
+ private List<Resource> waypoints;
+ private CompletableFuture<List<Variable>> callback;
+
+ public RouteJob(RouterConfiguration config, Route route, CompletableFuture<List<Variable>> callback) {
+ super("Compute route");
+ Objects.requireNonNull(callback, "Callback must be non-null");
+ setUser(true);
+ setRule(new ObjectIdentitySchedulingRule(route));
+ this.config = config;
+ this.waypoints = RoutePersistence.toResources(route.waypoints());
+ this.callback = callback;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ List<Router> routers = Activator.getInstance().getRouteService().routers();
+ for (Router router : routers) {
+ try {
+ List<Variable> path = router.findShortestPath(config, waypoints);
+ if (!path.isEmpty()) {
+ callback.complete(path);
+ return Status.OK_STATUS;
+ }
+ } catch (RoutingException e) {
+ LOGGER.error("Routing failed for waypoints {} and router {}", waypoints, router, e);
+ callback.completeExceptionally(e);
+ }
+ }
+ LOGGER.info("No router could calculate route between waypoints {}. Available routers: {}", waypoints, routers);
+ return Status.OK_STATUS;
+ }
+
+}