From d9895d7c86891e76e9008fd39cfe98fbaa545e15 Mon Sep 17 00:00:00 2001
From: Nikita Konev <nikit.cpp@yandex.ru>
Date: Wed, 1 Nov 2023 10:49:02 +0400
Subject: [PATCH] Optimize extraneous calls to chat from storage's
 cleanFilesOfDeletedChatTask

---
 storage/tasks/clean_files_of_deleted_chat.go | 62 +++++++++++++-------
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/storage/tasks/clean_files_of_deleted_chat.go b/storage/tasks/clean_files_of_deleted_chat.go
index da189f1c6..186912bd7 100644
--- a/storage/tasks/clean_files_of_deleted_chat.go
+++ b/storage/tasks/clean_files_of_deleted_chat.go
@@ -2,6 +2,7 @@ package tasks
 
 import (
 	"context"
+	"fmt"
 	"github.com/ehsaniara/gointerlock"
 	redisV8 "github.com/go-redis/redis/v8"
 	"github.com/minio/minio-go/v7"
@@ -38,44 +39,65 @@ type CleanFilesOfDeletedChatService struct {
 
 func (srv *CleanFilesOfDeletedChatService) doJob() {
 	ct := context.Background()
-	filenameChatPrefix := "chat/"
-	srv.processChats(filenameChatPrefix, ct)
+	srv.processChats(ct)
 }
 
-func (srv *CleanFilesOfDeletedChatService) processChats(filenameChatPrefix string, c context.Context) {
+func (srv *CleanFilesOfDeletedChatService) processChats(c context.Context) {
+	filenameChatPrefix := "chat/"
+
 	logger.Logger.Infof("Starting cleaning files of deleted chats job")
-	var objects <-chan minio.ObjectInfo = srv.minioClient.ListObjects(c, srv.minioBucketsConfig.Files, minio.ListObjectsOptions{
+
+	// get only top-level chats (no recursive)
+	var objectsChats <-chan minio.ObjectInfo = srv.minioClient.ListObjects(c, srv.minioBucketsConfig.Files, minio.ListObjectsOptions{
 		Prefix:    filenameChatPrefix,
-		Recursive: true,
+		Recursive: false,
 	})
 
-	for objInfo := range objects {
+	for chatObjInfo := range objectsChats {
 		// here in minio 'chat/108/'
-		logger.Logger.Debugf("Start processing minio key '%v'", objInfo.Key)
-		chatId, err := utils.ParseChatId(objInfo.Key)
+		logger.Logger.Debugf("Start processing minio key '%v'", chatObjInfo.Key)
+		chatId, err := utils.ParseChatId(chatObjInfo.Key)
 		if err != nil {
-			logger.Logger.Errorf("Unable to extract chat id from %v", objInfo.Key)
+			logger.Logger.Errorf("Unable to extract chat id from %v", chatObjInfo.Key)
 			continue
 		}
-		logger.Logger.Debugf("Successfully get chatId '%v'", chatId)
+		logger.Logger.Debugf("Successfully got chatId '%v'", chatId)
+
 
-		exists, err := srv.chatClient.CheckIsChatExists(chatId, c)
+		// check chat's existence
+		chatExists, err := srv.chatClient.CheckIsChatExists(chatId, c)
 		if err != nil {
-			logger.Logger.Errorf("Unable to chech existence of chat id from %v", objInfo.Key)
+			logger.Logger.Errorf("Unable to chech existence of chat id %v", chatId)
 			continue
 		}
-		if !exists {
-			logger.Logger.Infof("Deleting file(directory) object %v", objInfo.Key)
-			err := srv.minioClient.RemoveObject(c, srv.minioBucketsConfig.Files, objInfo.Key, minio.RemoveObjectOptions{})
-			if err != nil {
-				logger.Logger.Errorf("Object file %v has been cleared from minio with error: %v", objInfo.Key, err)
+
+
+		// performing cleanup in minio - getting subfolders (recursively)
+		filenameChatFilesPrefix := fmt.Sprintf("chat/%v/", chatId)
+		var objectsOfChat <-chan minio.ObjectInfo = srv.minioClient.ListObjects(c, srv.minioBucketsConfig.Files, minio.ListObjectsOptions{
+			Prefix:    filenameChatFilesPrefix,
+			Recursive: true,
+		})
+		for objInfo := range objectsOfChat {
+			// here in minio 'chat/108/'
+			logger.Logger.Debugf("Start processing minio key '%v'", objInfo.Key)
+
+			if !chatExists {
+				logger.Logger.Infof("Deleting file(directory) object %v", objInfo.Key)
+				err := srv.minioClient.RemoveObject(c, srv.minioBucketsConfig.Files, objInfo.Key, minio.RemoveObjectOptions{})
+				if err != nil {
+					logger.Logger.Errorf("Object file %v has been cleared from minio with error: %v", objInfo.Key, err)
+				} else {
+					logger.Logger.Debugf("Object file %v has been cleared from minio successfully", objInfo.Key)
+				}
 			} else {
-				logger.Logger.Debugf("Object file %v has been cleared from minio successfully", objInfo.Key)
+				logger.Logger.Debugf("Chat %v is present, skipping", chatId)
 			}
-		} else {
-			logger.Logger.Debugf("Chat %v is present, skipping", chatId)
 		}
+
 	}
+
+
 	logger.Logger.Infof("End of processChats job")
 }