1.1.1. Allocation Service¶
The allocation service offers interfaces to manage exclusive access to interactive resources. A priority-based scheduling mechanism thereby assigns time slots to clients that request such access. Clients have to use the ResourceAllocation data type in order to specify their request which is then processed by the server. Based on further information given with the data type and the current availability of resources, requests can be approved, denied, altered, or terminated. The life-cycle of a single allocation request looks like the following from the client’s and server’s perspectives.
A client requests a fixed set of resources for a given time interval that might lie in the future. The server either rejects the request directly if there’s no fitting time slot by setting the request’s state to REJECTED and sending it back to the client. Otherwise, the server answers with a (possibly modified) slot and the SCHEDULED state. During the waiting for the beginning of the interval, a request can be superseded by other allocations, e.g., ones with higher priority. The server accordingly notifies the client with a CANCELLED state if there’s no matching interval available or alters the scheduled interval. As soon as time reaches the beginning of the interval, the server sends an ALLOCATED message to the client.
Besides one or more target resources and a time slot, the client has to provide the following information to allow for effective and meaningful scheduling: A priority, an initiator (human or system), and a numerical importance value. The allocation server evaluates information in the following order:
- Higher priority values are preferred.
- A human initiator is preferred over a system initiator.
- Higher importance values are preferred.
Within the ResourceAllocation data type, clients must propose a conflict resolution policy to the server, i.e., to preserve the interval completely, or to use the largest or earliest available interval within the given time slot. As a further influence mechanism, clients can also specify a constraints interval to give the server more flexibility in assigning a final time slot.
The term interactive resource refers to anything inside the apartment that can be used for interaction purposes and needs exclusive access in order to
properly fulfil its role properly during such an interaction. For example during verbal interaction, the text-to-speech module should only be used by a
single component (the dialog) at the time. Currently, this resource would be denoted by the scope with which it is addressed, e.g. /home/kitchen/saytask
.
As a consequence, scopes can then be treated hierarchically in the allocation server, i.e., resources with the same prefix interfer with each other.
If in our example another component had exclusive access to /home/kitchen
, it would also imply that /home/kitchen/saytask
is unavailable for the dialog.
A conflict occurs if the targeted interval overlaps in any of the requested resources with another interval referencing the same resource.
1.1.1.2. Version History¶
- Version 0.13 (currently in development)
- TimeUnit API (incl. microsecond precision)
- Compatibility with rta-lib 1.3, rst-utils 0.3
- Version 0.12
- Introduce permission tokens
- Use monitors for locking
- Version 0.11
- Split server from client library (rta-lib)
- Explicit completion strategies
- GUI enhancements (colorize by priority)
1.1.1.3. Resource specification¶
The Scene Configuration, Scenario Coordination , and Task Arbitration use Ini files to specify which resources the requested routine occupies at the allocation service. A resources section specification thereby resembles the ResourceAllocation data type. A single such section can be present in each configuration file for a scene, scenario, or task. All fields are optional but the default values depend on the server component. The following values are valid:
[resources]
policy = (PRESERVE|MAXIMUM|FIRST)
priority = (NO|LOW|NORMAL|HIGH|URGENT|EMERGENCY)
initiator = (SYSTEM|HUMAN)
importance = unsigned int (only supported from rst 0.17+)
duration = unsigned long (evaluated as milliseconds from now)
maximum = unsigned long (evaluated as milliseconds from now)
ids = colon-separated array of string identifiers
description = string
1.1.1.4. Direct RSB communication¶
The allocation service is available at the following default scope which can be overridden at runtime:
SCOPE_ALLOCATION=/coordination/allocation/
If you want to use the allocation service in your component (client), all you have to do is exchange the ResourceAllocation data type with the server component and listen to the given signals. Simply send a message with REQUESTED as the state and the server will try to schedule your slot under the given id. It notifies you at the time a change occurs by updating the according fields of the data type. Every time the client sends a message under the same id, the server will reply with the current status of the allocation with the same id.
As a client, you should only execute your resource modifiction routines during the ALLOCATED and RELEASED signals.
1.1.1.5. Usage of the Java client library (rta-lib)¶
1.1.1.5.1. Set up dependencies¶
- Use the following as a dependency via maven:
- Add the following dependency to your
pom.xml
- Add the following dependency to your
<dependency>
<groupId>de.citec.csra</groupId>
<artifactId>rta-lib</artifactId>
<version>[1.2,1.3-SNAPSHOT)</version>
</dependency>
1.1.1.5.2. Code examples¶
The following code snippet allocates two resources simultaneously and waits for them to be released.
// Import the following:
import de.citec.csra.allocation.cli.AllocatableResource;
import de.citec.csra.allocation.cli.ExecutableResource;
import de.citec.csra.allocation.cli.ExecutableResource.Completion;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import rsb.InitializeException;
import rsb.RSBException;
import rst.communicationpatterns.ResourceAllocationType.ResourceAllocation.*;
// Specify resource allocation
AllocatableResource res = new AllocatableResource(
"Example 1",
Policy.MAXIMUM,
Priority.NORMAL,
Initiator.SYSTEM,
0,
2000,
TimeUnit.MILLISECONDS,
"/some/resource",
"/some/other/resource");
// Start server communication
res.startup();
// Await certain states
res.await(300, TimeUnit.MILLISECONDS, State.SCHEDULED);
res.await(300, TimeUnit.MILLISECONDS, State.ALLOCATED);
res.await(300, TimeUnit.MILLISECONDS, State.RELEASED);
The next example describes how to use an executable resource which allows you to specify user-code that is run on allocation and interrupted when the resource becomes unavailable. A completion value defines if the resource should be released immediately after the execute method has finished, or the resources should be kept allocated (and/or monitored).
// Specify executable part (like with a callable) and its resources
ExecutableResource<String> exe = new ExecutableResource<String>(
"Example 2",
Policy.MAXIMUM,
Priority.NORMAL,
Initiator.SYSTEM,
0,
2000,
TimeUnit.MILLISECONDS,
Completion.RETAIN,
"/some/resource",
"/some/other/resource") {
@Override
public String execute() throws ExecutionException, InterruptedException {
// intense resource modification happens
Thread.sleep(1000);
return "slept well";
}
};
// Start server communication
exe.startup();