= Design Goals
# To allow clients to express their requirements for state management without regard to the specific mechanisms that will be used to meet them.
# To free clients from understanding the details of state management, allowing them to focus on the use of state within their application.
# To match up clients with the state management provider that best meets the requirements they specify. Clients express these requirements by asking for 'capabilties' that should be supported by any state management provider they will use.
# To allow state management providers to innovate and provide unique value to state management clients (this is achieved by providers implementing and declaring capabilities and by the State Management runtime matching clients to their 'best fit' provider)
# Make core interfaces lean, such that:
## any provider can implement them fully (without having to leave some methods unimplemented only to throw UnsupportedOperationException)
## users need not write code to handle exceptions raised by using 'unimplemented' methods in the provider.
## interfaces/methods that are not considered 'core' functionality of State Management will be represented using capabilities.
# Interfaces and packages should be arranged by audience. The target audiences are user, provider, and platform. It should be clear for any audience which interfaces apply to them.
= Main Concepts
StateContainer is a '''container''' around a user-defined state value. It allows State Management to decorate a user-defined state value with system-defined attributes and behaviors. An instance of StateContainer has at least the following conceptual attributes:
* A globally unique key
* A value of a user-defined type
* Tracking information
A StateContainer instance has a globally unique key. This key can be used to identify a StateContainer instance from among the space of all other StateContainer instances, regardless of type, underlying provider, etc.
This key is composed of (at least) two components
* A user-specified key. This key can be of any type the user desires
* Extra information needed to generate a globally unique identifier (GUID)
The user should be able to retrieve and manipulate the StateContainer instance via the user-defined key even though the system thinks of it in terms of its GUID.
A value may represent any type of data. It may or may not be a 'data structure'. Values could represent data streams, etc. Regardless of the type of data held in the value, we '''must''' have a Java type to represent the value. State Management does not provide any native Java type for values. The Java type is always user-defined.
The java type for a value may define an interface to manipulate or change the data within a value. If such an interface is available, the value is considered 'mutable'. If not, the value is considered 'immutable'. For example, a Java POJO might be mutable whereas a Java String is always immutable.
In order to support flexible handling of mutable and immutable values, StateContainer must include a method to make a wholesale replacement of the value contained within a StateContainer instance.
=== Tracking Information
The StateManagerProvider may need to track certain information about a StateContainer object, and users may find it useful to have some tracking information as well. Common tracking information might be:
* Creation timestamp
* Last update timestamp
StateManager is a manager for StateContainer instances and the lifecycle control of StateContainer instances. At a minimum, StateManager must allow:
* Create a StateContainer instance
* Delete a StateContainer instance
* Retrieve a StateContainer instance via its key/GUID
This is a factory for StateManager instances, and used by clients. It is backed/implemented by a StateManagerProvider. The provider is invisible to the client as the client never uses it directly. A StateManagerFactory has the following conceptual attributes/behaviors:
* Provider name (the name of the provider that backs/implements the factory)
* Create a StateManager
* Check for the existence of a StateManager
* List the capabilities the StateManager was configured to support.
The client is matched with a StateManagerFactory by performing a 'factory query' specifying any of the following:
* Provider name
* Capabilities a StateManager produced by the factory should support
TODO: We need to agree on the mechanism for representing and performing the 'factory query'.
This is the main interface providers for State Management use to expose their capabilities. The StateManagerProvider interface is also a StateManagerFactory, a factory for StateManager instances. The provider that implements StateManagerProvider also implements StateManagerFactory, StateManager and StateContainer, so it is the source of all behavior for those interfaces.
A provider must implement the base State Management interfaces (StateManagerProvider, StateManager, StateContainer). It can then choose to implement any other capabiliities it wishes. The provider makes its capabilties known via the StateManagerProvider interface.
StateManagerProvider instances are then registered (at runtime). This registration makes the provider's StateManagerFactory available to clients.
A capability is some behavior or function that a provider offers that goes above and beyond those defined in the base interfaces for State Management (StateManagerProvider, StateManager, StateContainer). Capabilities may define a specific quality of service (QoS) such as the ability to durably store state data in the face of machine crashes. Capabilities may define specific behaviors like the ability to group operations on state data into transactions that allow the entire group of operations to be committed or rolled back as a unit. In some cases, these specific behaviors may require an extra functional interface, beyond those defined in the core of State Management.
A capability definition includes:
* A unique name by which both clients and providers will refer to it
* Optionally, the Java class name of any extra functional interface required to make use of the capability (for example, a transactional capability would require some method to request the commit or rollback of a transaction).
* Optionally, configuration parameter definitions that describe any configuration that needs to be specified by the client in order to obtain the correct behavior from the capability (also in our transaction example, we may need to request a specific transaction isolation to be used for the transaction, such as 'repeatable read' or 'serializable').