Overview of StateManagement (JSR350)
What is State?
- A unit of business data. A single unit of state is called a state object.
- Each state object tracks a single contents object we call it's ‘value’
- State is separate from the business logic that consumes and manipulates it
- A state object is uniquely identified by a key. This key is composed of a namespace + simple key value and is globally unique.
- [Mircea - so we have a 'state object' which is composed from a 'key' and a 'value'? In that case a better name might be 'state entry' - users might get the term easier as it is very similar in structure with the Map.Entry]
- [Mitch - interesting thought. Note, we have an interface called javax.state.State in the API. Would you propose we call that java.state.StateEntry instead?]
- [Pete - Linking to an existing API concept such as Map.Entry is a good idea but IMO in this case it is not a good analogy. A Map has an entry (i.e. key value pair) and is therefore called a Map.Entry, however, in the case of the state what is state an entry in? StateManager with StateManagerEntry would be the equivalent I think. I'm not sure the entry word adds enough meaning.]
- E.g., For a servlet container:
- a given session id (call it <jsession id value>) could be the simple key
- namespace might be 'javax.servlet.Session'
- unique key then becomes javax.servlet.Session<jsession id value>
- A state object's value has a type, and a java binding that exposes that type for manipulation within java code
- E.g, For a servlet container and Session state
- state object value (or contents) would be represented as a java.util.Map.
- keys and values in the map represent the session data the application-specific servlet code cares about
- servlet specification/container only defines that there is a Map for the session, and that each has a unique id, and not the keys/values within the map
- State objects are created, have a finite/specified lifetime, and are then destroyed. This lifetime is application-defined and may range from fractions of a second to years. The lifetime might be enforced by the application, or by the state management layer.
Examples of State
- HttpSession [lifetime is usually short once session is idle, enforced by servlet container]
- Web Services
- Reliable Messaging Sequence State [protocol defines max lifetime and an idle timeout. Can live for seconds to years]
- Secure Conversation Tokens [protocol defines lifetime, but usually it is short for security reasons]
- Conversational State [arbitrary lifetime specified by user, can be seconds to years]
What does it mean to 'Manage' State?
- Store and catalog state objects
- Retrieve state objects
- Via a primary key (single state object returned)
- Via some type of query (zero or more objects returned)
- Handle expiry and purging of state objects to avoid infinitely expanding pools of data
- Handle updates/removals of state objects with a specified QoS, such as...
- Concurrency control (isolating individual consumers from the updates of others)
- Fault tolerance
A system that intends to manage user state objects should support pluggability of multiple 'providers' that can bring different capabilities to bear for different customer needs. A provider of state management services (hereafter known as a state management provider) may have capabilities that make it more or less appropriate for a given scenario than another provider.
Why JSR 350 when we have JPA/JDBC/etc.?
JPA and JDBC are both heavily focused on relational databases. They do a *great* job of managing data in this type of store. Other persistence schemes expect data to be other forms, like XML, etc. But, in general, existing technologies for persistence tend to be heavily focused on a single storage paradigm. They generally require a considerable amount of prior knowledge and setup for the application layer to make use of them.
In short, using existing persistence technologies requires a tight binding to particular type of persistence you want to use. This works well if your application will run in a known and heavily controlled environment.
However, sometimes you can't know or tightly control the types of persistence available in your environment. Consider the following examples:
- An application deployed to a public cloud
- A traditional application that must support pluggable persistence
Both these examples are a poor fit for existing persistence architectures. JSR350 is intended to bridge the gap between this type of application and existing (and future) persistence providers.
With JSR350, applications declare their requirements for state management, and the state management system matches them to providers that can meet those requirements.
Goals of the StateManagement JSR
- 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 provider to innovate and provide unique value to state management clients (this is achieved by matching clients to their 'best fit' provider)
- a given environment may contain many providers for state management.
- a client may request:
- to manage Java objects of type com.myco.Foo
- to enforce a specific lifetime for Foo objects
- that Foo objects be managed in a durable fashion, surviving host failures, etc.
- to query for Foo objects using various fields available on Foo objects
- state management then pairs the client up with a 'best match' provider
- client can work with Foo objects with no regard to how or where those objects are stored.
- client doesn't have to worry about resource usage issues, availability guarantees, topology concerns, etc.
- client focuses purely on providing value derived from manipulating/displaying/etc. Foo objects.
What is a 'Capability'
A capability is some behavior or function that a provider offers that can be expressed in a programmatic way. 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.
A capability definition includes:
- A unique name
- 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').
Relationship between State Consumer and Producer (JSR350 View)
JSR347 View (JSR350 as Consumer)
JSR347 View (JSR350 as Producer)