diff --git a/.env b/.env index 6d4b81c..bacac01 100644 --- a/.env +++ b/.env @@ -14,3 +14,7 @@ SDU_SERVERS=http://10.211.55.2:7777 #Firebase Credentials FIREBASE_CREDENTIALS_PATH=serviceAccount.json + +#Каждые сколько дней будет очищаться буфер (максимальная дистанция синхронизации сообщений) +BUFFER_CLEANUP_DAYS=7 + diff --git a/src/main/java/im/rosetta/Boot.java b/src/main/java/im/rosetta/Boot.java index 2e339e5..1a45a6a 100644 --- a/src/main/java/im/rosetta/Boot.java +++ b/src/main/java/im/rosetta/Boot.java @@ -52,7 +52,7 @@ import im.rosetta.packet.Packet6Message; import im.rosetta.packet.Packet7Read; import im.rosetta.packet.Packet8Delivery; import im.rosetta.packet.Packet9DeviceNew; - +import im.rosetta.service.services.BufferCleanupService; import io.orprotocol.Server; import io.orprotocol.Settings; import io.orprotocol.packet.PacketManager; @@ -73,6 +73,7 @@ public class Boot { private ServerAdapter serverAdapter; private ClientManager clientManager; private OnlineManager onlineManager; + private BufferCleanupService bufferCleanupService; /** * Конструктор по умолчанию, использует порт 3000 для сервера @@ -96,6 +97,14 @@ public class Boot { 30 ), packetManager, this.serverAdapter); this.clientManager = new ClientManager(server); + /** + * Каждые сколько дней будет очищаться буфер (это влияет на синхронизацию сообщений, так + * как при синхронизации клиент запрашивает пакеты из буфера за последние 7 дней, если этот параметр будет меньше, + * то клиенты не смогут синхронизировать старые сообщения) + */ + int cleanupEveryDays = System.getenv("BUFFER_CLEANUP_DAYS") != null ? + Integer.parseInt(System.getenv("BUFFER_CLEANUP_DAYS")) : 7; + this.bufferCleanupService = new BufferCleanupService(cleanupEveryDays, this.logger); } /** @@ -141,6 +150,7 @@ public class Boot { this.registerAllExecutors(); this.registerAllEvents(); this.printBootMessage(); + this.bufferCleanupService.start(); return this; }catch(Exception e){ this.logger.error(Color.RED + "Booting error, stack trace:"); diff --git a/src/main/java/im/rosetta/database/repository/BufferRepository.java b/src/main/java/im/rosetta/database/repository/BufferRepository.java index aee28e3..7a15357 100644 --- a/src/main/java/im/rosetta/database/repository/BufferRepository.java +++ b/src/main/java/im/rosetta/database/repository/BufferRepository.java @@ -9,4 +9,18 @@ public class BufferRepository extends Repository { super(Buffer.class); } + /** + * Удаляет все записи страше чем timestampMs + * @param timestampMs метка времени в миллисекундах, все записи с меткой времени меньше которой будут удалены + */ + public void deleteOlderThan(long timestampMs) { + this.executeInTransaction(session -> { + String hql = "DELETE FROM Buffer WHERE timestamp < :timestamp"; + session.createMutationQuery(hql) + .setParameter("timestamp", timestampMs) + .executeUpdate(); + return null; + }); + } + } diff --git a/src/main/java/im/rosetta/service/services/BufferCleanupService.java b/src/main/java/im/rosetta/service/services/BufferCleanupService.java new file mode 100644 index 0000000..6193d1d --- /dev/null +++ b/src/main/java/im/rosetta/service/services/BufferCleanupService.java @@ -0,0 +1,52 @@ +package im.rosetta.service.services; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import im.rosetta.database.repository.BufferRepository; +import im.rosetta.logger.Logger; +import im.rosetta.logger.enums.Color; + +public class BufferCleanupService { + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private final BufferRepository bufferRepository = new BufferRepository(); + private final int cleanupEveryDays; + private final Logger logger; + + public BufferCleanupService(int cleanupEveryDays, Logger logger) { + this.cleanupEveryDays = cleanupEveryDays; + this.logger = logger; + } + + /** + * Запускает планировщик, который будет каждые 24 часа удалять из буфера + * пакеты старше чем cleanupEveryDays дней + */ + public void start() { + this.logger.info(Color.CYAN + "Sheduled cleanup buffer every " + this.cleanupEveryDays + " days"); + scheduler.scheduleAtFixedRate( + this::cleanupOldPackets, + 0, //стартовая задержка 0, то есть сразу при запуске сервиса будет выполнена очистка буфера + 24, + TimeUnit.HOURS + ); + } + + /** + * Функция планировщика, которая удаляет из буфера пакеты старше чем cleanupEveryDays дней + */ + private void cleanupOldPackets() { + try { + long sevenDaysAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(this.cleanupEveryDays); + bufferRepository.deleteOlderThan(sevenDaysAgo); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void stop() { + scheduler.shutdown(); + } +} \ No newline at end of file