use of org.apache.ignite.internal.metastorage.client.SimpleCondition in project ignite-3 by apache.
the class DistributedConfigurationStorage method write.
/**
* {@inheritDoc}
*/
@Override
public CompletableFuture<Boolean> write(Map<String, ? extends Serializable> newValues, long curChangeId) {
assert curChangeId <= changeId.get();
assert lsnr != null : "Configuration listener must be initialized before write.";
if (curChangeId < changeId.get()) {
// updates configuration.
return CompletableFuture.completedFuture(false);
}
Set<Operation> operations = new HashSet<>();
for (Map.Entry<String, ? extends Serializable> entry : newValues.entrySet()) {
ByteArray key = new ByteArray(DISTRIBUTED_PREFIX + entry.getKey());
if (entry.getValue() != null) {
operations.add(Operations.put(key, ConfigurationSerializationUtil.toBytes(entry.getValue())));
} else {
operations.add(Operations.remove(key));
}
}
operations.add(Operations.put(MASTER_KEY, ByteUtils.longToBytes(curChangeId)));
// Condition for a valid MetaStorage data update. Several possibilities here:
// - First update ever, MASTER_KEY property must be absent from MetaStorage.
// - Current node has already performed some updates or received them from MetaStorage watch listener. In this
// case "curChangeId" must match the MASTER_KEY revision exactly.
// - Current node has been restarted and received updates from MetaStorage watch listeners after that. Same as
// above, "curChangeId" must match the MASTER_KEY revision exactly.
// - Current node has been restarted and have not received any updates from MetaStorage watch listeners yet.
// In this case "curChangeId" matches APPLIED_REV, which may or may not match the MASTER_KEY revision. Two
// options here:
// - MASTER_KEY is missing in local MetaStorage copy. This means that current node have not performed nor
// observed any configuration changes. Valid condition is "MASTER_KEY does not exist".
// - MASTER_KEY is present in local MetaStorage copy. The MASTER_KEY revision is unknown but is less than or
// equal to APPLIED_REV. Obviously, there have been no updates from the future yet. It's also guaranteed
// that the next received configuration update will have the MASTER_KEY revision strictly greater than
// current APPLIED_REV. This allows to conclude that "MASTER_KEY revision <= curChangeId" is a valid
// condition for update.
// Combining all of the above, it's concluded that the following condition must be used:
SimpleCondition condition = curChangeId == 0L ? Conditions.notExists(MASTER_KEY) : Conditions.revision(MASTER_KEY).le(curChangeId);
return metaStorageMgr.invoke(condition, operations, Set.of(Operations.noop()));
}
use of org.apache.ignite.internal.metastorage.client.SimpleCondition in project ignite-3 by apache.
the class DistributedConfigurationStorageTest method mockMetaStorageManager.
/**
* Creates a mock implementation of a {@link MetaStorageManager}.
*/
private MetaStorageManager mockMetaStorageManager() {
var mock = mock(MetaStorageManager.class);
when(mock.invoke(any(), anyCollection(), anyCollection())).thenAnswer(invocation -> {
SimpleCondition condition = invocation.getArgument(0);
Collection<Operation> success = invocation.getArgument(1);
Collection<Operation> failure = invocation.getArgument(2);
boolean invokeResult = metaStorage.invoke(toServerCondition(condition), success.stream().map(DistributedConfigurationStorageTest::toServerOperation).collect(toList()), failure.stream().map(DistributedConfigurationStorageTest::toServerOperation).collect(toList()));
return CompletableFuture.completedFuture(invokeResult);
});
try {
when(mock.range(any(), any())).thenAnswer(invocation -> {
ByteArray keyFrom = invocation.getArgument(0);
ByteArray keyTo = invocation.getArgument(1);
return new CursorAdapter(metaStorage.range(keyFrom.bytes(), keyTo == null ? null : keyTo.bytes()));
});
} catch (NodeStoppingException e) {
throw new RuntimeException(e);
}
return mock;
}
Aggregations