[CONTROLLER-524] Introduce example which shows read/write/retry cycle with OptimisticLockFailedException Created: 30/May/14 Updated: 03/Jul/14 Due: 30/Jun/14 Resolved: 03/Jul/14 |
|
| Status: | Resolved |
| Project: | controller |
| Component/s: | mdsal |
| Affects Version/s: | Helium |
| Fix Version/s: | None |
| Type: | Improvement | ||
| Reporter: | Tony Tkacik | Assignee: | Tony Tkacik |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Operating System: Windows |
||
| Issue Links: |
|
||||||||
| Description |
|
Introduce an example which will showcase proper handling |
| Comments |
| Comment by Tony Tkacik [ 30/Jun/14 ] |
| Comment by Rob Adams [ 30/Jun/14 ] |
|
The example isn't quite right. The logic needs to exhibit a read/modify/write loop and (in a synchronous pseudocode to make it easy to follow) it would look roughly like: while (true) { catch (ConcurrentModificationException) { // nothing to do here }} The read/modify part here is important for correctness, since if you get this exception if you just keep retrying your write you'll lose the data that was written by the other process or thread. |
| Comment by Tony Tkacik [ 01/Jul/14 ] |
|
Updated to: private void readWriteRetry() { Optional<DataObject> readed = writeTx.read(LogicalDatastoreType.OPERATIONAL,PATH).get(); Futures.addCallback(future, new FutureCallback<RpcResult<TransactionStatus>>() { @Override @Override if(t instanceof OptimisticLockFailedException) { LOG.error("Concurrent modification of data",e); readWriteRetry(); } } This example is bit harder to read than your pseudocode, but illustrates read/write/retry using ListenableFutures |
| Comment by Rob Adams [ 01/Jul/14 ] |
|
Looks much better, though this documentation really shouldn't be on this hidden page. I might change to: private void readWriteRetry(RelevantEvent event) { // ... DataObject modified = modifyData(readed, event); // ... }but this is not critical. |
| Comment by Rob Adams [ 01/Jul/14 ] |
|
By the way, do we recommend calling get() on the read operation future? Or are you supposed to write the double chain of async events? Is each module supposed to allocate its own executor or is there a global shared one to use? |
| Comment by Tony Tkacik [ 02/Jul/14 ] |
|
Futures.addCallback(Future,FutureCallback) for callback uses thread in which future completed (e.g. MD-SAL thread in this use cases). Futures.addCallback(Future,FutureCallback,Executor) uses executor of your choice. We do not have global shared executor. |