com.nimbusds.infinispan.persistence.sql.ExpiredEntryReaper Maven / Gradle / Ivy
package com.nimbusds.infinispan.persistence.sql;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;
import static org.jooq.impl.DSL.table;
import net.jcip.annotations.ThreadSafe;
import org.infinispan.metadata.InternalMetadata;
import org.infinispan.metadata.impl.PrivateMetadata;
import org.infinispan.persistence.spi.AdvancedCacheExpirationWriter;
import org.infinispan.persistence.spi.AdvancedCacheWriter;
import org.infinispan.persistence.spi.MarshallableEntry;
import org.infinispan.persistence.spi.MarshallableEntryFactory;
import org.jooq.DSLContext;
import org.jooq.Record;
import com.nimbusds.infinispan.persistence.common.InfinispanEntry;
/**
* Expired entry reaper.
*/
@ThreadSafe
class ExpiredEntryReaper {
/**
* The Infinispan marshallable entry factory.
*/
private final MarshallableEntryFactory mEntryFactory;
/**
* The DSL context.
*/
private final DSLContext dsl;
/**
* The SQL record transformer.
*/
private final SQLRecordTransformer recordTransformer;
/**
* The SQL record wrapper.
*/
private final Function recordWrapper;
/**
* Creates a new reaper for expired entries.
*
* @param mEntryFactory The Infinispan marshallable entry factory.
* @param dsl The DSL context.
* @param recordTransformer The SQL record transformer.
* @param recordWrapper The SQL record wrapper to use.
*/
public ExpiredEntryReaper(final MarshallableEntryFactory mEntryFactory,
final DSLContext dsl,
final SQLRecordTransformer recordTransformer,
final Function recordWrapper) {
assert mEntryFactory != null;
this.mEntryFactory = mEntryFactory;
assert dsl != null;
this.dsl = dsl;
assert recordTransformer != null;
this.recordTransformer = recordTransformer;
assert recordWrapper != null;
this.recordWrapper = recordWrapper;
}
/**
* Purges the expired persisted entries according to their metadata
* timestamps (if set / persisted).
*
* @param purgeListener The purge listener. Must not be {@code null}.
*/
public void purge(final AdvancedCacheWriter.PurgeListener super K> purgeListener) {
final long now = new Date().getTime();
// The keys for deletion
List forDeletion = new LinkedList<>();
dsl.select()
.from(table(recordTransformer.getTableName()))
.stream()
.forEach(record -> {
RetrievedSQLRecord retrievedRecord = recordWrapper.apply(record);
InfinispanEntry infinispanEntry = recordTransformer.toInfinispanEntry(retrievedRecord);
InternalMetadata metadata = infinispanEntry.getMetadata();
if (metadata == null) {
return; // no metadata found
}
if (metadata.isExpired(now)) {
// Mark record for deletion
forDeletion.add(infinispanEntry.getKey());
}
});
int counter = 0;
for (K key: forDeletion) {
// Delete SQL record
int numDeleted = dsl.deleteFrom(table(recordTransformer.getTableName()))
.where(recordTransformer.resolveSelectionConditions(key))
.execute();
if (numDeleted == 1) {
// Notify listener, interested in the Infinispan entry key
purgeListener.entryPurged(key);
counter++;
}
}
Loggers.SQL_LOG.debug("[IS0128] SQL store: Purged {} expired {} cache entries", counter, recordTransformer.getTableName());
}
/**
* Purges the expired persisted entries according to their metadata
* timestamps (if set / persisted), with an extended listener for the
* complete purged entry.
*
* @param purgeListener The purge listener. Must not be {@code null}.
*/
public void purgeExtended(final AdvancedCacheExpirationWriter.ExpirationPurgeListener purgeListener) {
final long now = new Date().getTime();
// The entries for deletion
List> forDeletion = new LinkedList<>();
dsl.select()
.from(table(recordTransformer.getTableName()))
.stream()
.forEach(record -> {
RetrievedSQLRecord retrievedRecord = recordWrapper.apply(record);
InfinispanEntry infinispanEntry = recordTransformer.toInfinispanEntry(retrievedRecord);
InternalMetadata metadata = infinispanEntry.getMetadata();
if (metadata == null) {
return; // no metadata found
}
if (metadata.isExpired(now)) {
// Mark record for deletion
forDeletion.add(infinispanEntry);
}
});
int counter = 0;
for (InfinispanEntry en: forDeletion) {
// Delete SQL record
int numDeleted = dsl.deleteFrom(table(recordTransformer.getTableName()))
.where(recordTransformer.resolveSelectionConditions(en.getKey()))
.execute();
if (numDeleted == 1) {
// Notify listener, interested in the Infinispan entry
MarshallableEntry mEntry =
mEntryFactory.create(
en.getKey(),
en.getValue(),
en.getMetadata(),
PrivateMetadata.empty(),
en.created(),
en.lastUsed()
);
purgeListener.marshalledEntryPurged(mEntry);
counter++;
}
}
Loggers.SQL_LOG.debug("[IS0128] SQL store: Purged {} expired {} cache entries", counter, recordTransformer.getTableName());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy