All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentcs.components.kernel.Scheduler Maven / Gradle / Ivy

There is a newer version: 6.2.0
Show newest version
/**
 * Copyright (c) The openTCS Authors.
 *
 * This program is free software and subject to the MIT license. (For details,
 * see the licensing information (LICENSE.txt) you should have received with
 * this copy of the software.)
 */
package org.opentcs.components.kernel;

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.opentcs.components.Lifecycle;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.model.TCSResource;
import org.opentcs.data.model.Vehicle;

/**
 * Manages resources used by clients (vehicles) to help prevent both collisions and deadlocks.
 * 

* Every client usually interacts with the Scheduler according to the following * workflow: *

*
    *
  1. * Initially, the client calls * {@link #allocateNow(org.opentcs.components.kernel.Scheduler.Client, java.util.Set) allocateNow()} * when a vehicle pops up somewhere in the driving course. * This usually happens either upon kernel startup or when a vehicle communicates its current * position to the kernel for the first time. *
  2. *
  3. * Once a transport order is assigned to a vehicle, the client calls * {@link #claim(org.opentcs.components.kernel.Scheduler.Client, java.util.List) claim()} with the * complete sequence of resource sets the vehicle needs to process the transport order - usually * each containing a point and the path leading to it. *
  4. *
  5. * As the vehicle processes the transport order, the client subsequently calls * {@link #allocate(org.opentcs.components.kernel.Scheduler.Client, java.util.Set) allocate()} for * resources needed next (for reaching the next point on the route). * The Scheduler asynchronously calls back either * {@link Client#allocationSuccessful(java.util.Set)} or * {@link Client#allocationFailed(java.util.Set)}, informing the client about the result. * Upon allocating the resources for the client, it also implicitly removes them from the head of * the client's claim sequence. *
  6. *
  7. * As the vehicle passes points (and paths) on the route, the client calls * {@link #free(org.opentcs.components.kernel.Scheduler.Client, java.util.Set) free()} for resources * it does not need any more, allowing these resources to be allocated by other clients. *
  8. *
*

* At the end of this process, the client's claim sequence is empty, and only the most recently * allocated resources are still assigned to it, reflecting the vehicle's current position. * (If the vehicle has disappeared from the driving course after processing the transport order, the * client would call {@link #freeAll(org.opentcs.components.kernel.Scheduler.Client) freeAll()} to * inform the Scheduler about this.) *

*/ public interface Scheduler extends Lifecycle { /** * The key of a path property defining the direction in which a vehicle is entering a block when * it's taking the path. */ String PROPKEY_BLOCK_ENTRY_DIRECTION = "tcs:blockEntryDirection"; /** * Sets/Updates the resource claim for a vehicle. *

* Claimed resources are resources that a vehicle will eventually require for executing * its movements in the future, but for which it does not request allocation, yet. * Claiming resources provides information to the scheduler about future allocations and their * intended order, allowing the scheduler to consider these information for its resource * planning. *

*

* Resources can be claimed by multiple vehicles at the same time. * This is different from allocations: * Only a single vehicle can allocate a resource at the same time. *

*

* This method is supposed to be called only from the kernel executor thread. *

* * @param client The client claiming the resources. * @param resourceSequence The sequence of resources claimed. May be empty to clear the client's * claim. */ void claim( @Nonnull Client client, @Nonnull List>> resourceSequence ); /** * Requests allocation of the given resources. * The client will be informed via a callback to * {@link Client#allocationSuccessful(java.util.Set)} or * {@link Client#allocationFailed(java.util.Set)} whether the allocation was successful or not. *
    *
  • * Clients may only allocate resources in the order they have previously * {@link #claim(org.opentcs.components.kernel.Scheduler.Client, java.util.List) claim()}ed them. *
  • *
  • * Upon allocation, the scheduler will implicitly remove the set of allocated resources from (the * head of) the client's claim sequence. *
  • *
  • * As a result, a client may only allocate the set of resources at the head of its claim sequence. *
  • *
*

* This method is supposed to be called only from the kernel executor thread. *

* * @param client The client requesting the resources. * @param resources The resources to be allocated. * @throws IllegalArgumentException If the set of resources to be allocated is not equal to the * next set in the sequence of currently claimed resources, or if the client has already * requested resources that have not yet been granted. * @see #claim(org.opentcs.components.kernel.Scheduler.Client, java.util.List) */ void allocate( @Nonnull Client client, @Nonnull Set> resources ) throws IllegalArgumentException; /** * Checks if the resulting system state is safe if the given set of resources * would be allocated by the given client immediately. *

* This method is supposed to be called only from the kernel executor thread. *

* * @param client The client requesting the resources. * @param resources The requested resources. * @return {@code true} if the given resources are safe to be allocated by the given client, * otherwise {@code false}. */ boolean mayAllocateNow( @Nonnull Client client, @Nonnull Set> resources ); /** * Informs the scheduler that a set of resources are to be allocated for the given client * immediately. *

* Note the following: *

*
    *
  • * This method should only be called in urgent/emergency cases, for instance if a vehicle has been * moved to a different point manually, which has to be reflected by resource allocation in the * scheduler. *
  • *
  • * Unlike * {@link #allocate(org.opentcs.components.kernel.Scheduler.Client, java.util.Set) allocate()}, * this method does not block, i.e. the operation happens synchronously. *
  • *
  • * This method does not implicitly deallocate or unclaim any other resources for the * client. *
  • *
*

* This method is supposed to be called only from the kernel executor thread. *

* * @param client The client requesting the resources. * @param resources The resources requested. * @throws ResourceAllocationException If it's impossible to allocate the given set of resources * for the given client. */ void allocateNow( @Nonnull Client client, @Nonnull Set> resources ) throws ResourceAllocationException; /** * Releases a set of resources allocated by a client. *

* This method is supposed to be called only from the kernel executor thread. *

* * @param client The client releasing the resources. * @param resources The resources released. Any resources in the given set not allocated by the * given client are ignored. */ void free( @Nonnull Client client, @Nonnull Set> resources ); /** * Releases all resources allocated by the given client. *

* This method is supposed to be called only from the kernel executor thread. *

* * @param client The client. */ void freeAll( @Nonnull Client client ); /** * Releases all pending resource allocations for the given client. *

* This method is supposed to be called only from the kernel executor thread. *

* * @param client The client. */ void clearPendingAllocations( @Nonnull Client client ); /** * Explicitly triggers a rescheduling run during which the scheduler tries to allocate resources * for all waiting clients. *

* This method is supposed to be called only from the kernel executor thread. *

*/ void reschedule(); /** * Returns all resource allocations as a map of client IDs to resources. *

* This method is supposed to be called only from the kernel executor thread. *

* * @return All resource allocations as a map of client IDs to resources. */ @Nonnull Map>> getAllocations(); /** * Informs the scheduler that a set of resources was successfully prepared in order of allocating * them to a client. *

* This method is supposed to be called only from the kernel executor thread. *

* * @param module The module a preparation was necessary for. * @param client The client that requested the preparation/allocation. * @param resources The resources that are now prepared for the client. */ void preparationSuccessful( @Nonnull Module module, @Nonnull Client client, @Nonnull Set> resources ); /** * Defines callback methods for clients of the resource scheduler. */ interface Client { /** * Returns an ID string for this client. * The returned string should be unique among all clients in the system. * * @return An unique ID string for this client. */ @Nonnull String getId(); /** * Returns a reference to the {@link Vehicle} that this client is related to. * * @return A reference to the {@link Vehicle} that this client is related to or {@code null}, if * this client is not related to any {@link Vehicle}. */ @Nullable TCSObjectReference getRelatedVehicle(); /** * Called when resources have been reserved for this client. * * @param resources The resources reserved. * @return true if, and only if, this client accepts the resources allocated. A * return value of false indicates this client does not need the given resources * (any more), freeing them implicitly, but not restoring any previous claim. */ boolean allocationSuccessful( @Nonnull Set> resources ); /** * Called if it was impossible to allocate a requested set of resources for this client. * * @param resources The resources which could not be reserved. */ void allocationFailed( @Nonnull Set> resources ); } /** * A scheduler module. */ interface Module extends Lifecycle { /** * Informs this module about a client's current allocation state. * * @param client The client. * @param alloc The client's currently allocated resources. * @param remainingClaim The client's remaining claim. */ void setAllocationState( @Nonnull Client client, @Nonnull Set> alloc, @Nonnull List>> remainingClaim ); /** * Checks if the resulting system state is safe if the given set of resources * would be allocated by the given resource user. * * @param client The ResourceUser requesting resources set. * @param resources The requested resources. * @return true if this module thinks the given resources may be allocated for the * given client. */ boolean mayAllocate( @Nonnull Client client, @Nonnull Set> resources ); /** * Lets this module prepare the given resources so they can be allocated to a client. * * @param client The client the resources are being prepared for. * @param resources The resources to be prepared. */ void prepareAllocation( @Nonnull Client client, @Nonnull Set> resources ); /** * Checks if this module is done preparing the given resources for a client. * * @param client The client the resources are being prepared for. * @param resources The resources to be checked. * @return true if the resoruces are prepared for a client. */ boolean hasPreparedAllocation( @Nonnull Client client, @Nonnull Set> resources ); /** * Informs this module about resources being fully released by a client. * * @param client The client releasing the resources. * @param resources The resources being released. */ void allocationReleased( @Nonnull Client client, @Nonnull Set> resources ); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy