use of org.apache.ignite.internal.metastorage.server.EntryEvent in project ignite-3 by apache.
the class WatchCursor method next.
/**
* {@inheritDoc}
*/
@Override
public WatchEvent next() {
storage.lock().readLock().lock();
try {
if (!hasNext()) {
throw new NoSuchElementException();
}
List<EntryEvent> evts = new ArrayList<>();
long lastSeenRevision = currentRevision;
// Iterate over the keys of the current revision and get all matching entries.
for (; nativeIterator.isValid(); nativeIterator.next()) {
byte[] rocksKey = nativeIterator.key();
byte[] rocksValue = nativeIterator.value();
long revision = revisionFromRocksKey(rocksKey);
lastSeenRevision = revision;
if (revision > currentRevision) {
// There are no more keys for the current revision
break;
}
byte[] key = rocksKeyToBytes(rocksKey);
if (predicate.test(key)) {
Value val = bytesToValue(rocksValue);
Entry newEntry;
if (val.tombstone()) {
newEntry = Entry.tombstone(key, revision, val.updateCounter());
} else {
newEntry = new Entry(key, val.bytes(), revision, val.updateCounter());
}
Entry oldEntry = storage.doGet(key, revision - 1, false);
evts.add(new EntryEvent(oldEntry, newEntry));
}
}
currentHasNext = false;
// Go to the next revision
currentRevision = lastSeenRevision > currentRevision ? lastSeenRevision : currentRevision + 1;
checkIterator(nativeIterator);
return new WatchEvent(evts);
} finally {
storage.lock().readLock().unlock();
}
}
use of org.apache.ignite.internal.metastorage.server.EntryEvent in project ignite-3 by apache.
the class MetaStorageListener method onWrite.
/**
* {@inheritDoc}
*/
@Override
public void onWrite(Iterator<CommandClosure<WriteCommand>> iter) {
while (iter.hasNext()) {
CommandClosure<WriteCommand> clo = iter.next();
WriteCommand command = clo.command();
if (command instanceof PutCommand) {
PutCommand putCmd = (PutCommand) command;
storage.put(putCmd.key(), putCmd.value());
clo.result(null);
} else if (command instanceof GetAndPutCommand) {
GetAndPutCommand getAndPutCmd = (GetAndPutCommand) command;
Entry e = storage.getAndPut(getAndPutCmd.key(), getAndPutCmd.value());
clo.result(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
} else if (command instanceof PutAllCommand) {
PutAllCommand putAllCmd = (PutAllCommand) command;
storage.putAll(putAllCmd.keys(), putAllCmd.values());
clo.result(null);
} else if (command instanceof GetAndPutAllCommand) {
GetAndPutAllCommand getAndPutAllCmd = (GetAndPutAllCommand) command;
Collection<Entry> entries = storage.getAndPutAll(getAndPutAllCmd.keys(), getAndPutAllCmd.vals());
List<SingleEntryResponse> resp = new ArrayList<>(entries.size());
for (Entry e : entries) {
resp.add(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
}
clo.result(new MultipleEntryResponse(resp));
} else if (command instanceof RemoveCommand) {
RemoveCommand rmvCmd = (RemoveCommand) command;
storage.remove(rmvCmd.key());
clo.result(null);
} else if (command instanceof GetAndRemoveCommand) {
GetAndRemoveCommand getAndRmvCmd = (GetAndRemoveCommand) command;
Entry e = storage.getAndRemove(getAndRmvCmd.key());
clo.result(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
} else if (command instanceof RemoveAllCommand) {
RemoveAllCommand rmvAllCmd = (RemoveAllCommand) command;
storage.removeAll(rmvAllCmd.keys());
clo.result(null);
} else if (command instanceof GetAndRemoveAllCommand) {
GetAndRemoveAllCommand getAndRmvAllCmd = (GetAndRemoveAllCommand) command;
Collection<Entry> entries = storage.getAndRemoveAll(getAndRmvAllCmd.keys());
List<SingleEntryResponse> resp = new ArrayList<>(entries.size());
for (Entry e : entries) {
resp.add(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
}
clo.result(new MultipleEntryResponse(resp));
} else if (command instanceof InvokeCommand) {
InvokeCommand cmd = (InvokeCommand) command;
boolean res = storage.invoke(toCondition(cmd.condition()), toOperations(cmd.success()), toOperations(cmd.failure()));
clo.result(res);
} else if (command instanceof MultiInvokeCommand) {
MultiInvokeCommand cmd = (MultiInvokeCommand) command;
StatementResult res = storage.invoke(toIf(cmd.iif()));
clo.result(new StatementResultInfo(res.bytes()));
} else if (command instanceof RangeCommand) {
RangeCommand rangeCmd = (RangeCommand) command;
IgniteUuid cursorId = rangeCmd.getCursorId();
Cursor<Entry> cursor = (rangeCmd.revUpperBound() != -1) ? storage.range(rangeCmd.keyFrom(), rangeCmd.keyTo(), rangeCmd.revUpperBound()) : storage.range(rangeCmd.keyFrom(), rangeCmd.keyTo());
cursors.put(cursorId, new CursorMeta(cursor, CursorType.RANGE, rangeCmd.requesterNodeId()));
clo.result(cursorId);
} else if (command instanceof CursorNextCommand) {
CursorNextCommand cursorNextCmd = (CursorNextCommand) command;
CursorMeta cursorDesc = cursors.get(cursorNextCmd.cursorId());
if (cursorDesc == null) {
clo.result(new NoSuchElementException("Corresponding cursor on the server side is not found."));
return;
}
try {
if (cursorDesc.type() == CursorType.RANGE) {
Entry e = (Entry) cursorDesc.cursor().next();
clo.result(new SingleEntryResponse(e.key(), e.value(), e.revision(), e.updateCounter()));
} else if (cursorDesc.type() == CursorType.WATCH) {
WatchEvent evt = (WatchEvent) cursorDesc.cursor().next();
List<SingleEntryResponse> resp = new ArrayList<>(evt.entryEvents().size() * 2);
for (EntryEvent e : evt.entryEvents()) {
Entry o = e.oldEntry();
Entry n = e.entry();
resp.add(new SingleEntryResponse(o.key(), o.value(), o.revision(), o.updateCounter()));
resp.add(new SingleEntryResponse(n.key(), n.value(), n.revision(), n.updateCounter()));
}
clo.result(new MultipleEntryResponse(resp));
}
} catch (NoSuchElementException e) {
clo.result(e);
}
} else if (command instanceof CursorCloseCommand) {
CursorCloseCommand cursorCloseCmd = (CursorCloseCommand) command;
CursorMeta cursorDesc = cursors.remove(cursorCloseCmd.cursorId());
if (cursorDesc == null) {
clo.result(null);
return;
}
try {
cursorDesc.cursor().close();
} catch (Exception e) {
throw new IgniteInternalException(e);
}
clo.result(null);
} else if (command instanceof WatchRangeKeysCommand) {
WatchRangeKeysCommand watchCmd = (WatchRangeKeysCommand) command;
IgniteUuid cursorId = watchCmd.getCursorId();
Cursor<WatchEvent> cursor = storage.watch(watchCmd.keyFrom(), watchCmd.keyTo(), watchCmd.revision());
cursors.put(cursorId, new CursorMeta(cursor, CursorType.WATCH, watchCmd.requesterNodeId()));
clo.result(cursorId);
} else if (command instanceof WatchExactKeysCommand) {
WatchExactKeysCommand watchCmd = (WatchExactKeysCommand) command;
IgniteUuid cursorId = watchCmd.getCursorId();
Cursor<WatchEvent> cursor = storage.watch(watchCmd.keys(), watchCmd.revision());
cursors.put(cursorId, new CursorMeta(cursor, CursorType.WATCH, watchCmd.requesterNodeId()));
clo.result(cursorId);
} else if (command instanceof CursorsCloseCommand) {
CursorsCloseCommand cursorsCloseCmd = (CursorsCloseCommand) command;
Iterator<CursorMeta> cursorsIter = cursors.values().iterator();
while (cursorsIter.hasNext()) {
CursorMeta cursorDesc = cursorsIter.next();
if (cursorDesc.requesterNodeId().equals(cursorsCloseCmd.nodeId())) {
try {
cursorDesc.cursor().close();
} catch (Exception e) {
throw new IgniteInternalException(e);
}
cursorsIter.remove();
}
}
clo.result(null);
} else {
assert false : "Command was not found [cmd=" + command + ']';
}
}
}
use of org.apache.ignite.internal.metastorage.server.EntryEvent in project ignite-3 by apache.
the class ItMetaStorageServiceTest method testWatchOnUpdate.
@Test
public void testWatchOnUpdate() throws Exception {
org.apache.ignite.internal.metastorage.server.WatchEvent expectedEvent = new org.apache.ignite.internal.metastorage.server.WatchEvent(List.of(new org.apache.ignite.internal.metastorage.server.EntryEvent(new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 2 }, new byte[] { 20 }, 1, 1), new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 2 }, new byte[] { 21 }, 2, 4)), new org.apache.ignite.internal.metastorage.server.EntryEvent(new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 3 }, new byte[] { 20 }, 1, 2), new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 3 }, new byte[] {}, 2, 5)), new org.apache.ignite.internal.metastorage.server.EntryEvent(new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 4 }, new byte[] { 20 }, 1, 3), new org.apache.ignite.internal.metastorage.server.Entry(new byte[] { 4 }, new byte[] {}, 3, 6))));
ByteArray keyFrom = new ByteArray(new byte[] { 1 });
ByteArray keyTo = new ByteArray(new byte[] { 10 });
long rev = 2;
when(mockStorage.watch(keyFrom.bytes(), keyTo.bytes(), rev)).thenAnswer(invocation -> {
var cursor = mock(Cursor.class);
when(cursor.hasNext()).thenReturn(true);
when(cursor.next()).thenReturn(expectedEvent);
return cursor;
});
CountDownLatch latch = new CountDownLatch(1);
IgniteUuid watchId = metaStorageSvc.watch(keyFrom, keyTo, rev, new WatchListener() {
@Override
public boolean onUpdate(@NotNull WatchEvent event) {
Collection<EntryEvent> expectedEvents = expectedEvent.entryEvents();
Collection<org.apache.ignite.internal.metastorage.client.EntryEvent> actualEvents = event.entryEvents();
assertEquals(expectedEvents.size(), actualEvents.size());
Iterator<EntryEvent> expectedIterator = expectedEvents.iterator();
Iterator<org.apache.ignite.internal.metastorage.client.EntryEvent> actualIterator = actualEvents.iterator();
while (expectedIterator.hasNext() && actualIterator.hasNext()) {
org.apache.ignite.internal.metastorage.server.EntryEvent expectedEntryEvent = expectedIterator.next();
org.apache.ignite.internal.metastorage.client.EntryEvent actualEntryEvent = actualIterator.next();
assertArrayEquals(expectedEntryEvent.oldEntry().key(), actualEntryEvent.oldEntry().key().bytes());
assertArrayEquals(expectedEntryEvent.oldEntry().value(), actualEntryEvent.oldEntry().value());
assertArrayEquals(expectedEntryEvent.entry().key(), actualEntryEvent.newEntry().key().bytes());
assertArrayEquals(expectedEntryEvent.entry().value(), actualEntryEvent.newEntry().value());
}
latch.countDown();
return true;
}
@Override
public void onError(@NotNull Throwable e) {
// Within given test it's not expected to get here.
fail();
}
}).get();
latch.await();
metaStorageSvc.stopWatch(watchId).get();
}
Aggregations