public interface CriticalRepositoryInteraction
PassEntity are not interleaved within
the scope of the running JVM. This means that code executed within a CriticalRepositoryInteraction should
never observe changes to the same PassEntity resulting from another thread.
Interactions with the repository are not atomic or transactional. CriticalRepositoryInteraction
does what it can to insure safe, concurrent, interaction with repository resources, but repository resources can be
modified at any time by agents outside the scope of the running JVM. Therefore, implementations executing this
CriticalRepositoryInteraction must be prepared to handle UpdateConflictException.
Clients of this interface must understand that while the boilerplate for interacting with the repository is provided by an implementation, there are no atomicity or transactional guarantees provided.
Example usage The following example demonstrates how the critical path of building theDepositSubmission model is insulated
from other threads that may be wanting to modify the same Submission.
Submission is provided to the CriticalInteraction, which will retrieve
the most recent state of resource from the repositorySubmission retrieved from the repository has the required state
for the critical path (the building of the DepositSubmission)CriticalRepositoryInteraction.CriticalResult
to record success or failure of the operation). Note the post-condition can operate on the just the
PassEntity, or the PassEntity and the Object returned by the critical
pathSubmission that met the
pre-condition. The critical path can return an object that is not a PassEntity, in this
case, a DepositSubmissionPassEntity will be submitted to the
repository for update. Implementations should provide for the handling of any
ConflictUpdateExceptions.CriticalInteraction
CriticalResult<DepositSubmission, Submission> result =
critical.performCritical(submission.getId(), Submission.class,
// pre-condition which is supplied the resource retrieved from submission.getId()
(submission) -> {
return submissionPolicy.accept(submission);
},
// post-condition which is supplied the resource resulting from updating the repository with the modified
// resource resulting from the critical path; that is to say, critical path executes, a round trip to the
// repository occurs, and the result of the round trip is supplied to the post-condition
(submission) -> {
return submission.getAggregatedDepositStatus() == IN_PROGRESS;
}
// critical path
(submission) -> {
DepositSubmission ds = null;
try {
ds = fcrepoModelBuilder.build(submission.getId().toString());
} catch (InvalidModel invalidModel) {
throw new RuntimeException(invalidModel.getMessage(), invalidModel);
}
submission.setAggregatedDepositStatus(IN_PROGRESS);
return ds;
});
| Modifier and Type | Interface and Description |
|---|---|
static class |
CriticalRepositoryInteraction.CriticalResult<R,T>
Encapsulates the result of a critical interaction with the repository.
|
| Modifier and Type | Method and Description |
|---|---|
<R,T extends org.dataconservancy.pass.model.PassEntity> |
performCritical(URI uri,
Class<T> clazz,
Predicate<T> precondition,
BiPredicate<T,R> postcondition,
Function<T,R> critical)
Execute a critical interaction with the repository, subject to
precondition. |
<R,T extends org.dataconservancy.pass.model.PassEntity> |
performCritical(URI uri,
Class<T> clazz,
Predicate<T> precondition,
Predicate<T> postcondition,
Function<T,R> critical)
Execute a critical interaction with the repository, subject to
precondition. |
<R,T extends org.dataconservancy.pass.model.PassEntity> CriticalRepositoryInteraction.CriticalResult<R,T> performCritical(URI uri, Class<T> clazz, Predicate<T> precondition, Predicate<T> postcondition, Function<T,R> critical)
precondition. Success of the interaction
depends on the evaluation of postcondition.
See the other form of performCritical if the postcondition needs to evaluate both the PassEntity resource and the
return from the critical path.
T - the type of PassEntityR - the type of the result returned by criticaluri - the uri of the PassEntity which is the subject of the critical pathclazz - the concrete Class of the PassEntity represented by uriprecondition - precondition that must evaluate to true for the critical path to executepostcondition - postcondition that must evaluate to true for the CriticalResult to be
considered successfulcritical - the critical interaction with the repository, which may return a result of type RCriticalResult recording the success or failure of the interaction, and any results.<R,T extends org.dataconservancy.pass.model.PassEntity> CriticalRepositoryInteraction.CriticalResult<R,T> performCritical(URI uri, Class<T> clazz, Predicate<T> precondition, BiPredicate<T,R> postcondition, Function<T,R> critical)
precondition. Success of the interaction
depends on the evaluation of postcondition.
See the other form of performCritical if the postcondition only needs to evaluate the PassEntity resource.
T - the type of PassEntityR - the type of the result returned by criticaluri - the uri of the PassEntity which is the subject of the critical pathvclazz - the concrete Class of the PassEntity represented by uriprecondition - precondition that must evaluate to true for the critical path to executepostcondition - postcondition that must evaluate to true for the CriticalResult to be
considered successfulcritical - the critical interaction with the repository, which may return a result of type RCriticalResult recording the success or failure of the interaction, and any results.Copyright © 2019. All rights reserved.