All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fi.evolver.basics.spring.messaging.MessageDataCleaner Maven / Gradle / Ivy

package fi.evolver.basics.spring.messaging;

import static fi.evolver.utils.timing.TimingUtils.begin;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Component;

import fi.evolver.basics.spring.clean.DataCleaner;
import fi.evolver.basics.spring.job.ResultState;
import fi.evolver.basics.spring.job.TaskStatusService;
import fi.evolver.basics.spring.messaging.entity.MessageData;
import fi.evolver.basics.spring.triggerable.AbstractTriggerable;
import fi.evolver.basics.spring.triggerable.TriggerableException;
import fi.evolver.utils.arg.Arg;
import fi.evolver.utils.arg.IntArg;
import fi.evolver.utils.arg.LongArg;
import fi.evolver.utils.timing.TimingUtils.AutoCloser;


@Component
public class MessageDataCleaner extends AbstractTriggerable {
	private static final LongArg MIN_AGE_MS = new LongArg("MinAgeMs", 0L, null);
	private static final IntArg MAX_BATCH_SIZE = new IntArg("MaxBatchSize", 1, null, 1_000);
	private static final IntArg SELECT_LIMIT = new IntArg("SelectLimit", 1, null, 10_000);
	private static final LongArg MAX_RUN_TIME_MS = new LongArg("MaxRunTimeMs", 1L, null, 30_000L);

	private static final List> ARGS = Arrays.asList(
			MIN_AGE_MS,
			MAX_BATCH_SIZE,
			SELECT_LIMIT,
			MAX_RUN_TIME_MS);


	private final DataCleaner dataCleaner;
	private final MessageDataRepository messageDataRepository;
	private final TaskStatusService taskStatusService;


	@Autowired
	public MessageDataCleaner(
			DataCleaner dataCleaner,
			MessageDataRepository messageDataRepository,
			TaskStatusService taskStatusService) {
		this.dataCleaner = dataCleaner;
		this.messageDataRepository = messageDataRepository;
		this.taskStatusService = taskStatusService;
	}


	@Override
	protected ResultState run(Map args) throws TriggerableException {
		long now = System.currentTimeMillis();
		long stopAt = now + MAX_RUN_TIME_MS.get(args);
		long maxUpdateTime = now - MIN_AGE_MS.get(args);

		int batchSize = MAX_BATCH_SIZE.get(args);
		int selectLimit = SELECT_LIMIT.get(args);

		List ids = fetchDeletableIds(maxUpdateTime, selectLimit);
		int deleted = deleteInBatches(ids, batchSize, stopAt);

		return ResultState.ok(deleted > 0, "Deleted %s messages", deleted);
	}


	private List fetchDeletableIds(long maxUpdateTime, int selectLimit) {
		try (AutoCloser t = begin("Find")) {
			return messageDataRepository.findReadyForDeletion(maxUpdateTime, PageRequest.of(0, selectLimit));
		}
	}


	private int deleteInBatches(List ids, int batchSize, long stopAt) {
		int deleted = 0;
		for (int i = 0; i < ids.size(); i += batchSize) {
			taskStatusService.updateMessage("%d / %d", deleted, ids.size());
			try (AutoCloser t = begin("DeleteBatch")) {
				deleted += dataCleaner.deleteBatch(MessageData.class, ids.subList(i, Math.min(ids.size(), i + batchSize)));
				if (System.currentTimeMillis() > stopAt)
					break;
			}
		}
		return deleted;
	}


	@Override
	public List> getArgs() {
		return ARGS;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy