Interface StateSynchronizer<StateT extends Revisioned>
-
- Type Parameters:
StateT
- The type of the object whose updates are being synchronized.
- All Superinterfaces:
java.lang.AutoCloseable
public interface StateSynchronizer<StateT extends Revisioned> extends java.lang.AutoCloseable
Provides a means to have state that is synchronized between many processes. This provides a higher level abstraction overRevisionedStreamClient
.The pattern is to have an object of type StateT that can be updated by objects of type UpdateT. Each host can perform logic based on its current StateT object and apply updates by supplying a function to create UpdateT objects. Updates from other hosts can be obtained by calling
fetchUpdates()
The applying of updates can be conditional on the state that was provided to their generator being the most recent revision, and retrying if it is not. This provides a strong consistency through optimistic concurrency.
As with any optimistic concurrency system, this works best when optimism is justified: i.e. The odds are good another host is not updating the state at the exact same time.
Because they are held in memory and transmitted over the network, state objects are updates should be relatively compact. Implementations might explicitly enforce size limits.
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static interface
StateSynchronizer.UpdateGenerator<StateT extends Revisioned>
A function which given a state object populates a list of updates that should be applied.static interface
StateSynchronizer.UpdateGeneratorFunction<StateT extends Revisioned,ReturnT>
Similar toStateSynchronizer.UpdateGenerator
but it also returns a result for the caller.
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description long
bytesWrittenSinceCompaction()
Calculates the number of bytes that have been written since the state has last been compacted by callingcompact(Function)
This may be useful when calculating when a compaction should occur.void
close()
Closes the StateSynchronizer and frees any resources associated with it.void
compact(java.util.function.Function<StateT,InitialUpdate<StateT>> compactor)
Provide a function that generates compacted version of localState so that we can drop some of the history updates.void
fetchUpdates()
Fetch and apply all updates needed to the state object held locally up to date.StateT
getState()
Gets the state object currently held in memory.void
initialize(InitialUpdate<StateT> initial)
This method can be used to provide an initial value for a new stream if the stream has not been previously initialized.void
updateState(StateSynchronizer.UpdateGenerator<StateT> updateGenerator)
Creates a new update for the latest state object and applies it atomically.<ReturnT> ReturnT
updateState(StateSynchronizer.UpdateGeneratorFunction<StateT,ReturnT> updateGenerator)
Similar toupdateState(UpdateGenerator)
but this version returns a result object supplied by theStateSynchronizer.UpdateGeneratorFunction
.void
updateStateUnconditionally(Update<StateT> update)
Persists the provided update.void
updateStateUnconditionally(java.util.List<? extends Update<StateT>> update)
Same asupdateStateUnconditionally(Update)
, except it persists multiple updates at the same time so they will not be interleaved with other updates.
-
-
-
Method Detail
-
getState
StateT getState()
Gets the state object currently held in memory. This is a non-blocking call.- Returns:
- Revisioned state object
-
fetchUpdates
void fetchUpdates()
Fetch and apply all updates needed to the state object held locally up to date.
-
updateState
void updateState(StateSynchronizer.UpdateGenerator<StateT> updateGenerator)
Creates a new update for the latest state object and applies it atomically. The UpdateGenerator provided will be passed the latest state object and a list which it can populate with any updates that need to be applied. These updates are recorded and applied conditionally on the state object that was passed to the function being up to date. If another process was applying an update in parallel, the state is updated and updateGenerator will be called again with the new state object so that it may generate new updates. (Which may be different from the one it previously generated) By re-creating the updates in this way, consistency is guaranteed. When this function returns the generated updates will have been applied to the local state.- Parameters:
updateGenerator
- A function that given the current state can supply updates that should be applied.
-
updateState
<ReturnT> ReturnT updateState(StateSynchronizer.UpdateGeneratorFunction<StateT,ReturnT> updateGenerator)
Similar toupdateState(UpdateGenerator)
but this version returns a result object supplied by theStateSynchronizer.UpdateGeneratorFunction
. This is useful if the calling code wishes to do something in response to the update. As an example suppose the update type was MyUpdate and each update and an associated key. Then it might be useful to return the updated keys:List<String> updated = stateSynchronizer.updateState((state, updates) -> { List<MyUpdate> toAdd = findUpdatesForState(state); updates.addAll(toAdd); return toAdd.stream().map(a -> a.getKey()).collect(Collectors.toList()); });
- Type Parameters:
ReturnT
- They type of the result returned by the updateGenerator- Parameters:
updateGenerator
- A function which give the state can supply updates that should be applied.- Returns:
- the result returned by the updateGenerator.
-
updateStateUnconditionally
void updateStateUnconditionally(Update<StateT> update)
Persists the provided update. To ensure consistent ordering of updates across hosts the update is not applied locally untilfetchUpdates()
is called.- Parameters:
update
- The update that all other processes should receive.
-
updateStateUnconditionally
void updateStateUnconditionally(java.util.List<? extends Update<StateT>> update)
Same asupdateStateUnconditionally(Update)
, except it persists multiple updates at the same time so they will not be interleaved with other updates.- Parameters:
update
- The updates that all other processes should receive.
-
initialize
void initialize(InitialUpdate<StateT> initial)
This method can be used to provide an initial value for a new stream if the stream has not been previously initialized. If the stream was already initialized nothing will be changed, and the local state will be updated as thoughfetchUpdates()
- Parameters:
initial
- The initializer for the state
-
bytesWrittenSinceCompaction
long bytesWrittenSinceCompaction()
Calculates the number of bytes that have been written since the state has last been compacted by callingcompact(Function)
This may be useful when calculating when a compaction should occur.- Returns:
- The number of bytes written since the last call to
compact(Function)
-
compact
void compact(java.util.function.Function<StateT,InitialUpdate<StateT>> compactor)
Provide a function that generates compacted version of localState so that we can drop some of the history updates.NOTE: If InitialUpdate returned does not generate local state exactly corruption will occur.
- Parameters:
compactor
- An generator of InitialUpdates given a state.
-
close
void close()
Closes the StateSynchronizer and frees any resources associated with it. (It may no longer be used)- Specified by:
close
in interfacejava.lang.AutoCloseable
- See Also:
AutoCloseable.close()
-
-