Как обрабатывать ошибки в программе - PullRequest
0 голосов
/ 17 октября 2019

У меня есть сервис, который использует для загрузки файла на AWS S3 . Я пытался использовать с goroutines и без загрузки файла. Если я загружаю файл без подпрограмм, он должен подождать до конца, а затем дать ответ, и если я использую подпрограммы, он будет работать в фоновом режиме и быстрее реагировать на клиентскую сторону.

Как насчет того, чтобы загрузитьне удалось, если я использую goroutines? И затем этот файл не загружен в AWS S3 ? Можете ли вы сказать мне, как справиться с этим, как?

вот моя функция для загрузки файла

func uploadToS3(s *session.Session, size int64, name string , buffer []byte)( string , error) {

    tempFileName := "pictures/" + bson.NewObjectId().Hex() + "-" + filepath.Base(name)

    _, err := s3.New(s).PutObject(&s3.PutObjectInput{
        Bucket:             aws.String("myBucketNameHere"),
        Key:                aws.String(tempFileName),
        ACL:                aws.String("public-read"),
        Body:               bytes.NewReader(buffer),
        ContentLength:      aws.Int64(int64(size)),
        ContentType:        aws.String(http.DetectContentType(buffer)),
        ContentDisposition: aws.String("attachment"),
        ServerSideEncryption: aws.String("AES256"),
        StorageClass:       aws.String("INTELLIGENT_TIERING"),
    })

    if err != nil {
        return "", err
    }

    return tempFileName, err
}

func UploadFile(db *gorm.DB) func(c *gin.Context) {
    return func(c *gin.Context) {
        file, err := c.FormFile("file")

        f, err := file.Open()
        if err != nil {
            fmt.Println(err)
        }

        defer f.Close()
        buffer := make([]byte, file.Size)
        _, _ = f.Read(buffer)
        s, err := session.NewSession(&aws.Config{
            Region: aws.String("location here"),
            Credentials: credentials.NewStaticCredentials(
                    "id",
                    "key",
                    "",
                ),
        })
        if err != nil {
            fmt.Println(err)
        }

        go uploadToS3(s, file.Size, file.Filename, buffer)

        c.JSON(200, fmt.Sprintf("Image uploaded successfully"))
    }
}

Я тоже подумал, а как насчет того, если есть много запросов на загрузку файла более 10000+ за 5-10 минут? какой-то файл не может быть загружен из-за слишком большого количества запросов?

Ответы [ 3 ]

1 голос
/ 17 октября 2019

Этот вопрос слишком широк для одного ответа. Вообще говоря, существует три возможных подхода:

  1. Дождитесь завершения ваших процедур для обработки любых ошибок.

  2. Убедитесь, что ваши программы могут обработать(или, возможно, игнорировать) любые ошибки, с которыми они сталкиваются, так что возвращение ошибки никогда не имеет значения.

  3. Пусть ваши программы запишут любые ошибки, для последующей обработки, возможно, человеком или, возможно, некоторымифункция очистки / повтора.

Какой подход лучше всего зависит от ситуации.

0 голосов
/ 17 октября 2019

Для любой асинхронной задачи, например, для загрузки файла в фоновом режиме, можно написать функцию загрузки таким образом, чтобы она возвращала chan error вызывающей стороне. Затем вызывающий может отреагировать на возможную ошибку загрузки файла (или ноль, если нет ошибки) позднее, прочитав из chan error.

Однако, если вы принимаете запросы на загрузку, я бы предложил вместосоздал подпрограмму загрузки работника, которая принимает загрузки файлов по каналу. Выходной канал «ошибка» может отслеживать успех / неудачу. И если необходимо, загруженная ошибка может быть записана обратно в исходную очередь канала загрузки (включая максимальное количество повторов и повторных попыток - поэтому проблемная полезная нагрузка не зацикливается вечно).

0 голосов
/ 17 октября 2019

Проблема в том, что при использовании goroutine, вы сразу же возвращаете сообщение об успехе вашему клиенту. Если это действительно так, это означает, что ваша программа должна быть в состоянии восстановиться в случае ошибки при загрузке на S3 (не теряйте изображение). Таким образом, либо вы позаботитесь об этом, либо асинхронно сообщаете своему клиенту, что загрузка не удалась, поэтому клиент может повторить попытку.

...