| 5885 | } |
| 5886 | |
| 5887 | ACTOR void checkWrites(Reference<TransactionState> trState, |
| 5888 | Future<Void> committed, |
| 5889 | Promise<Void> outCommitted, |
| 5890 | CommitTransactionRequest req) { |
| 5891 | state Version version; |
| 5892 | try { |
| 5893 | wait(committed); |
| 5894 | // If the commit is successful, by definition the transaction still exists for now. Grab the version, and don't |
| 5895 | // use it again. |
| 5896 | version = trState->committedVersion; |
| 5897 | outCommitted.send(Void()); |
| 5898 | } catch (Error& e) { |
| 5899 | outCommitted.sendError(e); |
| 5900 | return; |
| 5901 | } |
| 5902 | |
| 5903 | wait(delay(deterministicRandom()->random01())); // delay between 0 and 1 seconds |
| 5904 | |
| 5905 | state KeyRangeMap<MutationBlock> expectedValues; |
| 5906 | |
| 5907 | auto& mutations = req.transaction.mutations; |
| 5908 | state int mCount = mutations.size(); // debugging info for traceEvent |
| 5909 | |
| 5910 | for (int idx = 0; idx < mutations.size(); idx++) { |
| 5911 | if (mutations[idx].type == MutationRef::SetValue) |
| 5912 | expectedValues.insert(singleKeyRange(mutations[idx].param1), MutationBlock(mutations[idx].param2)); |
| 5913 | else if (mutations[idx].type == MutationRef::ClearRange) |
| 5914 | expectedValues.insert(KeyRangeRef(mutations[idx].param1, mutations[idx].param2), MutationBlock(true)); |
| 5915 | } |
| 5916 | |
| 5917 | try { |
| 5918 | state Transaction tr(trState->cx); |
| 5919 | tr.setVersion(version); |
| 5920 | state int checkedRanges = 0; |
| 5921 | state KeyRangeMap<MutationBlock>::Ranges ranges = expectedValues.ranges(); |
| 5922 | state KeyRangeMap<MutationBlock>::iterator it = ranges.begin(); |
| 5923 | for (; it != ranges.end(); ++it) { |
| 5924 | state MutationBlock m = it->value(); |
| 5925 | if (m.mutated) { |
| 5926 | checkedRanges++; |
| 5927 | if (m.cleared) { |
| 5928 | RangeResult shouldBeEmpty = wait(tr.getRange(it->range(), 1)); |
| 5929 | if (shouldBeEmpty.size()) { |
| 5930 | TraceEvent(SevError, "CheckWritesFailed") |
| 5931 | .detail("Class", "Clear") |
| 5932 | .detail("KeyBegin", it->range().begin) |
| 5933 | .detail("KeyEnd", it->range().end); |
| 5934 | return; |
| 5935 | } |
| 5936 | } else { |
| 5937 | Optional<Value> val = wait(tr.get(it->range().begin)); |
| 5938 | if (!val.present() || val.get() != m.setValue) { |
| 5939 | TraceEvent evt(SevError, "CheckWritesFailed"); |
| 5940 | evt.detail("Class", "Set").detail("Key", it->range().begin).detail("Expected", m.setValue); |
| 5941 | if (!val.present()) |
| 5942 | evt.detail("Actual", "_Value Missing_"); |
| 5943 | else |
| 5944 | evt.detail("Actual", val.get()); |
no test coverage detected