use of org.apache.ignite.internal.metastorage.client.WatchListener in project ignite-3 by apache.
the class DistributedConfigurationStorage method registerConfigurationListener.
/**
* {@inheritDoc}
*/
@Override
public synchronized void registerConfigurationListener(@NotNull ConfigurationStorageListener lsnr) {
if (this.lsnr == null) {
this.lsnr = lsnr;
// TODO: registerWatchByPrefix could throw OperationTimeoutException and CompactedException and we should
// TODO: properly handle such cases https://issues.apache.org/jira/browse/IGNITE-14604
metaStorageMgr.registerWatchByPrefix(DST_KEYS_START_RANGE, new WatchListener() {
@Override
public boolean onUpdate(@NotNull WatchEvent events) {
Map<String, Serializable> data = new HashMap<>();
Entry masterKeyEntry = null;
for (EntryEvent event : events.entryEvents()) {
Entry e = event.newEntry();
if (e.key().equals(MASTER_KEY)) {
masterKeyEntry = e;
} else {
String key = e.key().toString().substring(DISTRIBUTED_PREFIX.length());
Serializable value = e.value() == null ? null : ConfigurationSerializationUtil.fromBytes(e.value());
data.put(key, value);
}
}
// That means that masterKey update must be included in the batch.
assert masterKeyEntry != null;
long newChangeId = masterKeyEntry.revision();
assert newChangeId > changeId.get();
changeId.set(newChangeId);
lsnr.onEntriesChanged(new Data(data, newChangeId)).join();
return true;
}
@Override
public void onError(@NotNull Throwable e) {
// TODO: need to handle this case and there should some mechanism for registering new watch as far as
// TODO: onError unregisters failed watch https://issues.apache.org/jira/browse/IGNITE-14604
LOG.error("Meta storage listener issue", e);
}
});
} else {
LOG.warn("Configuration listener has already been set.");
}
}
use of org.apache.ignite.internal.metastorage.client.WatchListener in project ignite-3 by apache.
the class WatchAggregator method watchListener.
/**
* Produces the watch listener, which will dispatch events to appropriate watches.
*
* @param storeRevision action to commit keys-revision pair to persistent store for processed keys.
* @return watch listener, which will dispatch events to appropriate watches.
*/
private WatchListener watchListener(BiConsumer<Collection<IgniteBiTuple<ByteArray, byte[]>>, Long> storeRevision) {
// Copy watches to separate collection, because all changes on the WatchAggregator watches
// shouldn't be propagated to listener watches immediately.
// WatchAggregator will be redeployed with new watches if needed instead.
final LinkedHashMap<Long, Watch> cpWatches = new LinkedHashMap<>(watches);
return new WatchListener() {
@Override
public boolean onUpdate(@NotNull WatchEvent evt) {
// TODO: IGNITE-15858 Fix stopWatch may solve the issue.
synchronized (watches) {
processWatchEvents(evt);
}
return true;
}
/**
* Process watch events synchronously.
*
* @param evt Watch event.
*/
private void processWatchEvents(@NotNull WatchEvent evt) {
var watchIt = cpWatches.entrySet().iterator();
Collection<Long> toCancel = new ArrayList<>();
while (watchIt.hasNext()) {
Map.Entry<Long, Watch> entry = watchIt.next();
Watch watch = entry.getValue();
var filteredEvts = new ArrayList<EntryEvent>();
for (EntryEvent entryEvt : evt.entryEvents()) {
if (watch.keyCriterion().contains(entryEvt.oldEntry().key())) {
filteredEvts.add(entryEvt);
}
}
if (!filteredEvts.isEmpty()) {
if (!watch.listener().onUpdate(new WatchEvent(filteredEvts))) {
watchIt.remove();
toCancel.add(entry.getKey());
}
}
}
// to prevent finished watches from redeploy.
if (!toCancel.isEmpty()) {
cancelAll(toCancel);
}
var revision = 0L;
var entries = new ArrayList<IgniteBiTuple<ByteArray, byte[]>>();
for (EntryEvent entryEvt : evt.entryEvents()) {
revision = entryEvt.newEntry().revision();
entries.add(new IgniteBiTuple<>(entryEvt.newEntry().key(), entryEvt.newEntry().value()));
}
storeRevision.accept(entries, revision);
}
@Override
public void onError(@NotNull Throwable e) {
watches.values().forEach(w -> w.listener().onError(e));
}
};
}
Aggregations