kontenhumas-be/app/module/article_files/service/async_uploader.service.go

140 lines
3.6 KiB
Go

package service
import (
"context"
"github.com/minio/minio-go/v7"
"github.com/rs/zerolog"
"io"
"time"
)
// AsyncUploader menangani proses upload secara asynchronous
type UploadService interface {
UploadFile(ctx context.Context, minioClient *minio.Client, uploadID string, reader io.Reader, bucketName string, objectName string, size int64, contentType string) error
}
type uploadService struct {
uploadManager UploadManager
Log zerolog.Logger
}
func NewUploadService(uploadManager UploadManager, log zerolog.Logger) UploadService {
return &uploadService{
uploadManager: uploadManager,
Log: log,
}
}
func (u *uploadService) UploadFile(ctx context.Context, minioClient *minio.Client, uploadID string, reader io.Reader, bucketName string, objectName string, size int64, contentType string) error {
status := &UploadStatus{
FileName: objectName,
Size: size,
Progress: 0,
Status: "uploading",
ObjectName: objectName,
BucketName: bucketName,
StartTime: time.Now(),
}
u.uploadManager.Add(uploadID, status)
u.Log.Info().Str("timestamp", time.Now().
Format(time.RFC3339)).Str("Service:Resource", "UploadService::UploadFile").
Interface("add status", status).Msg("")
// Upload ke Minio
_, err := minioClient.PutObject(
ctx,
bucketName,
objectName,
reader,
size,
minio.PutObjectOptions{
ContentType: contentType,
PartSize: 10 * 1024 * 1024, // 10MB part size
},
)
if err != nil {
u.uploadManager.UpdateStatus(uploadID, "error", err)
u.Log.Info().Str("timestamp", time.Now().
Format(time.RFC3339)).Str("Service:Resource", "UploadService::UploadFile").
Interface("error when upload", err).Msg("")
}
u.uploadManager.UpdateStatus(uploadID, "completed", nil)
return nil
}
//func (au *UploadService) UploadFile() {
// // Buat context dengan timeout
// ctx, cancel := context.WithTimeout(au.ctx, 30*time.Minute)
// defer cancel()
//
// // Buat reader dari byte slice
// reader := bytes.NewReader(au.fileData)
// pipeReader, pipeWriter := io.Pipe()
//
// au.progressMap.Store(au.uploadID, 0.0)
//
// // Start goroutine to read from reader and write to pipe
// go func() {
// defer pipeWriter.Close()
// buf := make([]byte, au.partSize)
//
// totalParts := int(reader.Size() / au.partSize)
// if reader.Size()%au.partSize != 0 {
// totalParts++
// }
//
// for i := 0; i < totalParts; i++ {
// n, err := reader.Read(buf)
// if err != nil && err != io.EOF {
// log.Println("Error reading file:", err)
// return
// }
//
// if _, err := pipeWriter.Write(buf[:n]); err != nil {
// log.Println("Error writing to pipe:", err)
// return
// }
//
// progress := float64(i+1) / float64(totalParts) * 100
// au.progressMap.Store(au.uploadID, progress)
// au.uploadManager.UpdateProgress(au.uploadID, int(progress))
// }
// }()
//
// // Upload ke Minio
// _, err := au.minioClient.PutObject(
// ctx,
// au.bucketName,
// au.objectName,
// pipeReader,
// reader.Size(),
// minio.PutObjectOptions{
// ContentType: au.contentType,
// PartSize: 10 * 1024 * 1024, // 10MB part size
// },
// )
//
// if err != nil {
// log.Println("Error uploading file:", err)
// au.progressMap.Store(au.uploadID, "error")
// return
// }
//
// fmt.Printf("Uploading process for %s", au.objectName)
//
// if err != nil {
// uploadManager.UpdateStatus(au.uploadID, "error", err)
// fmt.Printf("Upload error for %s: %v\n", au.objectName, err)
// return
// }
//
// au.progressMap.Store(au.uploadID, 100)
// au.uploadManager.UpdateProgress(au.uploadID, 100)
// au.uploadManager.UpdateStatus(au.uploadID, "completed", nil)
//}