new setting for deleting old entries (fix #524)

This commit is contained in:
Athou
2014-12-04 10:22:57 +01:00
parent e40dd14bbf
commit 9110cfd923
11 changed files with 114 additions and 20 deletions

View File

@@ -110,6 +110,10 @@ public class CommaFeedConfiguration extends Configuration {
@Min(0)
private int keepStatusDays;
@NotNull
@Min(0)
private int maxFeedCapacity;
@NotNull
@Min(0)
private int refreshIntervalMinutes;

View File

@@ -15,6 +15,7 @@ import com.commafeed.backend.favicon.AbstractFaviconFetcher;
import com.commafeed.backend.favicon.DefaultFaviconFetcher;
import com.commafeed.backend.favicon.FacebookFaviconFetcher;
import com.commafeed.backend.favicon.YoutubeFaviconFetcher;
import com.commafeed.backend.task.OldEntriesCleanupTask;
import com.commafeed.backend.task.OldStatusesCleanupTask;
import com.commafeed.backend.task.OrphansCleanupTask;
import com.commafeed.backend.task.ScheduledTask;
@@ -49,6 +50,7 @@ public class CommaFeedModule extends AbstractModule {
Multibinder<ScheduledTask> taskMultibinder = Multibinder.newSetBinder(binder(), ScheduledTask.class);
taskMultibinder.addBinding().to(OldStatusesCleanupTask.class);
taskMultibinder.addBinding().to(OldEntriesCleanupTask.class);
taskMultibinder.addBinding().to(OrphansCleanupTask.class);
}
}

View File

@@ -1,11 +1,13 @@
package com.commafeed.backend.dao;
import java.util.Date;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.codec.digest.DigestUtils;
import org.hibernate.SessionFactory;
@@ -13,6 +15,9 @@ import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.QFeedEntry;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.mysema.query.Tuple;
import com.mysema.query.types.expr.NumberExpression;
@Singleton
public class FeedEntryDAO extends GenericDAO<FeedEntry> {
@@ -30,10 +35,27 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
return Iterables.getFirst(list, null);
}
public int delete(Date olderThan, int max) {
List<FeedEntry> list = newQuery().from(entry).where(entry.inserted.lt(olderThan)).limit(max).list(entry);
public List<FeedCapacity> findFeedsExceedingCapacity(long maxCapacity, long max) {
List<FeedCapacity> list = Lists.newArrayList();
NumberExpression<Long> count = entry.id.countDistinct();
List<Tuple> tuples = newQuery().from(entry).groupBy(entry.feed).having(count.gt(maxCapacity)).limit(max).list(entry.feed.id, count);
for (Tuple tuple : tuples) {
list.add(new FeedCapacity(tuple.get(entry.feed.id), tuple.get(count)));
}
return list;
}
public int deleteOldEntries(Long feedId, long max) {
List<FeedEntry> list = newQuery().from(entry).where(entry.feed.id.eq(feedId)).orderBy(entry.updated.asc()).limit(max).list(entry);
int deleted = list.size();
delete(list);
return deleted;
}
@AllArgsConstructor
@Getter
public static class FeedCapacity {
private Long id;
private Long capacity;
}
}

View File

@@ -1,9 +1,7 @@
package com.commafeed.backend.service;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -16,6 +14,7 @@ import org.hibernate.SessionFactory;
import com.commafeed.backend.dao.FeedDAO;
import com.commafeed.backend.dao.FeedEntryContentDAO;
import com.commafeed.backend.dao.FeedEntryDAO;
import com.commafeed.backend.dao.FeedEntryDAO.FeedCapacity;
import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.model.Feed;
@@ -75,23 +74,37 @@ public class DatabaseCleaningService {
return total;
}
public long cleanEntriesOlderThan(long value, TimeUnit unit) {
final Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -1 * (int) unit.toMinutes(value));
public long cleanEntriesForFeedsExceedingCapacity(final int maxFeedCapacity) {
long total = 0;
int deleted = 0;
do {
deleted = new UnitOfWork<Integer>(sessionFactory) {
while (true) {
List<FeedCapacity> feeds = new UnitOfWork<List<FeedCapacity>>(sessionFactory) {
@Override
protected Integer runInSession() throws Exception {
return feedEntryDAO.delete(cal.getTime(), BATCH_SIZE);
protected List<FeedCapacity> runInSession() throws Exception {
return feedEntryDAO.findFeedsExceedingCapacity(maxFeedCapacity, BATCH_SIZE);
}
}.run();
total += deleted;
log.info("removed {} entries", total);
} while (deleted != 0);
log.info("cleanup done: {} entries deleted", total);
if (feeds.isEmpty()) {
break;
}
for (final FeedCapacity feed : feeds) {
long remaining = feed.getCapacity() - maxFeedCapacity;
do {
final long rem = remaining;
int deleted = new UnitOfWork<Integer>(sessionFactory) {
@Override
protected Integer runInSession() throws Exception {
return feedEntryDAO.deleteOldEntries(feed.getId(), Math.min(BATCH_SIZE, rem));
};
}.run();
total += deleted;
remaining -= deleted;
log.info("removed {} entries for feeds exceeding capacity", total);
} while (remaining > 0);
}
}
log.info("cleanup done: {} entries for feeds exceeding capacity deleted", total);
return total;
}

View File

@@ -0,0 +1,43 @@
package com.commafeed.backend.task;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.RequiredArgsConstructor;
import com.commafeed.CommaFeedConfiguration;
import com.commafeed.backend.service.DatabaseCleaningService;
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton
public class OldEntriesCleanupTask extends ScheduledTask {
private final CommaFeedConfiguration config;
private final DatabaseCleaningService cleaner;
@Override
public void run() {
int maxFeedCapacity = config.getApplicationSettings().getMaxFeedCapacity();
if (maxFeedCapacity > 0) {
cleaner.cleanEntriesForFeedsExceedingCapacity(maxFeedCapacity);
}
}
@Override
public long getInitialDelay() {
return 5;
}
@Override
public long getPeriod() {
return 60;
}
@Override
public TimeUnit getTimeUnit() {
return TimeUnit.MINUTES;
}
}

View File

@@ -28,7 +28,7 @@ public class OldStatusesCleanupTask extends ScheduledTask {
@Override
public long getInitialDelay() {
return 10;
return 15;
}
@Override

View File

@@ -23,7 +23,7 @@ public class OrphansCleanupTask extends ScheduledTask {
@Override
public long getInitialDelay() {
return 5;
return 10;
}
@Override