• No results found

Adaptation Interface

3. Employing Roles in Decentralized Self-Adaptive Software Systems

3.2. Supporting Decentralized Run-time Adaptation

3.2.2. Adaptation Interface

The adaptation interface of the role runtime is a set of provided methods that allows the modification of the role-based application from a different process, e.g., the execu- tion management of the self-adaptive software system as depicted in Figure 3.1. We will rely on this interface specification in the next chapter where we outline the overall contribution of this thesis, which addresses the execution of distributed adaptations of role-based software systems without a central coordinator. In the following, the methods provided within this interface to allow the modification of the role-based application by the execution management, will be introduced.

create(roleType)

The create operation allows the creation of a new role instance within the local role runtime. Newly created role instances are in the Unbound state. The create operation takes the type of the role to instantiate as sole input parameter and returns the identifier unique within the respective local role runtime of the newly created role instance.

remove(roleInstance)

The remove operation removes the given role instance from the local role runtime. If the role instance that is supposed to be removed is in the Unbound state, the removal of the role will be performed and a boolean value indicating the result will be returned. If the role is in any other state than the Unbound state, the operation will not remove the instance and return unsuccessfully.

bind(playerInstance, roleInstance, compartmentInstance)

The bind operation establishes a plays relationship between a given player and a role instance within a given compartment. The bind operation takes the unique instance identifiers of role, player and compartment as input and returns a boolean value that indicates whether the plays relation could be established successfully or not. If a role is already bound to a player and a bind operation is issued affecting this role instance, this method returns false without changing the underlying run- time model of the application, i.e., the plays relation between the role instance and its player is not modified. This constraint is a result of the assumption that a role instance can only be played by exactly one player at any given point in time. If a role is intended to be bound to the player it is already played by, the operation will succeed without changing the underlying run-time model. Consequently, the bind operation moves the given role from the Unbound state to the Bound/Passive state, thus, not modifying the player’s exposed behavior yet, which is desirable if several adaptations have to be coordinated consistently, especially across multiple devices.

unbind(playerInstance, roleInstance, compartmentInstance)

The unbind operation is the inverse operation to the Bind operation and releases the plays relationship between a role and its player within the given compartment. The unbind operation takes the unique instance identifiers of role, player and com- partment as input and returns a boolean value that indicates whether the plays relationship could be released successfully or not. This method will only succeed if the role is in the Bound/Passive state before the unbind operation is issued and thus moves the given role to the Unbound state.

activate(roleInstance)

A newly created role is in the Bound/Passive state, which means it does not mod- ify the player’s behavior since it is not considered by the role runtime to execute application-specific behavior. Roles that are in the Bound/Passive state are reg- istered for the execution of application behavior by using the activate operation, which takes the unique instance identifier of the role instance to activate as sole input and returns a boolean value to indicate whether the activation was successful or not.

passivate(roleInstance)

The passivate operation is the inverse operation to the Activate operation and removes the given role instance from the list of roles considered by the runtime’s

3.2. Supporting Decentralized Run-time Adaptation dispatching mechanism for the execution of application behavior of the respective player. It takes the unique instance identifier of the role to passivate as sole input and returns a boolean value to indicate whether the role could be moved to the Bound/Passive state or not. When the role to passivate is currently active and processing a request, i.e., if it is currently performing application behavior, the passivate operation will not return unless the role had finished its current task and went to the idle state. For any given role, it is only possible to go from the Bound/Active/Idle state to the Bound/Passive state as it was discussed previously. getState(roleInstance)

This method is used to obtain the internal state information, which is returned through the return value of the method, of the given role. The internal state of a role describes application data stored within the attributes, for example, of the given role instance. A role of which state information is supposed to be obtained must be in the Bound/Passive life-cycle state at the time this operation is exe- cuted. Otherwise a defined error value will be returned to indicate that no state information could be obtained from the specified role instance. The criteria of the role to be in the Bound/Passive state for this method to succeed is also relevant to prevent the loss of application data. If a role was still allowed to perform compu- tations that could possibly alter its internal state after the state information was obtained within an adaptation process, the subsequently made changes would be lost.

setState(roleInstance, stateData)

Obtained state information from a different role can be set to the role instance specified within this method. The successful execution of this method is indicated through a boolean return value. This method only succeeds if the role instance supposed to receive the state information is in the Bound/Passive life-cycle state at the time the operation is executed. The rationale for the required life-cycle state of the role to be in before this method can be successfully executed is the same as for the just discussed getState method.

connect(roleInstance, remoteRole)

The connect operation establishes a collaboration between two instances of roles, which do not necessarily need to be located on the same physical computational device. The connect operation takes the local role instance identifier as first input parameter and a tuple denoted as remoteRole consisting of {address, role instance identif ier} as second input parameter and returns a boolean value to indicate

whether the collaboration could be established successfully. Similarly to the Bind operation, an established collaboration between two roles is not immediately active, but remains in a preliminary state until an Activate operation is invoked on the role. Consequently, the role does not necessarily need to be in a passive state when the connect operation is invoked.

disconnect(roleInstance, remoteRole)

The disconnect operation is the inverse operation to the Connect operation and releases the collaboration between two roles. The signature is identical to the Connect operation, consequently. Since an ongoing collaboration between two dif- ferent role instances is supposed to be released with this method, the local role runtime needs to ensure the role to reach the Bound/Passive state, i.e., a stable state to ensure no data in transit gets lost, in prior to the actual removal of the dispatch information.

Transitions between the life cycle states of a role (cf. Figure 3.2) denoted with a name that matches the name of the interface operation, are triggered by the invocation of the respective interface operation. Other interface methods are introduced to support the different scenarios introduced in Chapter 1.1.