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) //}