Немного увеличена стабильность работы, а также добавлены логи

This commit is contained in:
2025-12-25 23:16:27 +03:00
parent 6845219e94
commit 9754bf3f6c
3 changed files with 120 additions and 53 deletions

View File

@@ -6,13 +6,37 @@ import (
"io"
"os"
"path/filepath"
"time"
"gitea.unprism.ru/KRBL/Agate/models"
"gitea.unprism.ru/KRBL/Agate/store"
log "github.com/sirupsen/logrus"
)
const blobExtension = ".zip"
// progressReader — обертка для логирования
type progressReader struct {
reader io.Reader
totalRead int64
lastLog time.Time
snapshotID string
}
func (pr *progressReader) Read(p []byte) (int, error) {
n, err := pr.reader.Read(p)
pr.totalRead += int64(n)
// Логируем каждые 5 секунд
if time.Since(pr.lastLog) > 5*time.Second {
log.Printf("Snapshot %s download progress: %.2f MB downloaded",
pr.snapshotID, float64(pr.totalRead)/1024/1024)
pr.lastLog = time.Now()
}
return n, err
}
// fileSystemStore реализует интерфейс store.BlobStore с использованием локальной файловой системы.
type fileSystemStore struct {
baseDir string // Директория для хранения блобов (архивов)
@@ -47,23 +71,49 @@ func (fs *fileSystemStore) getBlobPath(snapshotID string) string {
// StoreBlob сохраняет данные из reader в файл в baseDir.
func (fs *fileSystemStore) StoreBlob(ctx context.Context, snapshotID string, reader io.Reader) (string, error) {
blobPath := fs.getBlobPath(snapshotID)
log.Printf("Starting to store blob for snapshot %s at %s", snapshotID, blobPath)
// Создаем или перезаписываем файл
file, err := os.Create(blobPath)
// Используем временный файл, чтобы не повредить (возможно) существующий валидный файл
// если загрузка упадет на середине.
tempPath := blobPath + ".tmp"
file, err := os.Create(tempPath)
if err != nil {
return "", fmt.Errorf("failed to create blob file %s: %w", blobPath, err)
return "", fmt.Errorf("failed to create temp blob file %s: %w", tempPath, err)
}
defer file.Close() // Гарантируем закрытие файла
defer file.Close()
// Копируем данные из ридера в файл
_, err = io.Copy(file, reader)
if err != nil {
// Если произошла ошибка копирования, удаляем неполный файл
os.Remove(blobPath)
return "", fmt.Errorf("failed to write data to blob file %s: %w", blobPath, err)
// Оборачиваем reader для логирования
pr := &progressReader{
reader: reader,
snapshotID: snapshotID,
lastLog: time.Now(),
}
// Возвращаем путь к созданному файлу
// Копируем данные
written, err := io.Copy(file, pr)
if err != nil {
file.Close()
os.Remove(tempPath) // Удаляем мусор
return "", fmt.Errorf("failed to write data to blob file %s: %w", tempPath, err)
}
// Важный момент: Sync, чтобы убедиться, что данные на диске
if err := file.Sync(); err != nil {
file.Close()
os.Remove(tempPath)
return "", fmt.Errorf("failed to sync file to disk: %w", err)
}
file.Close() // Закрываем перед переименованием
// Переименовываем временный файл в финальный (атомарная операция)
if err := os.Rename(tempPath, blobPath); err != nil {
return "", fmt.Errorf("failed to rename temp file to final blob: %w", err)
}
log.Printf("Successfully stored blob for snapshot %s. Total size: %.2f MB",
snapshotID, float64(written)/1024/1024)
return blobPath, nil
}