2017-06-26 1 views
1

En essayant de télécharger simultanément plusieurs fichiers à partir de S3 et de consolider leur contenu dans un tampon d'octets. Les fichiers sont au format csv. Mon code semble fonctionner la plupart du temps (8 à partir de 10 essais) .Mais il y a des instances qui après avoir inspecté le tampon consolidé, j'ai moins que ce que je devrais obtenir (habituellement pas plus de 100 lignes manquantes). Si le code est exécuté séquentiellement, ce problème n'apparaît pas. Mais j'ai besoin d'utiliser des goroutines pour la vitesse. sans les courses de données apparaissent, et les déclarations d'erreur que j'imprime ne s'impriment jamais.Téléchargement simultané de plusieurs fichiers à partir de S3 et consolidation de ceux-ci

Voici le code que j'utilise:

var pingsBuffer = aws.NewWriteAtBuffer([]byte{}) 
     //range over the contents of the index file 
    for _, file := range indexList { 
     wg.Add(1) 
     go download(key + string(file), pingsBuffer, &wg) 
    } 
    wg.Wait() 

et les fonctions de téléchargement (qui regroupe également les fichiers téléchargés)

func download(key string, buffer *aws.WriteAtBuffer, wg *sync.WaitGroup) { 

defer wg.Done() 

awsBuffer := aws.NewWriteAtBuffer([]byte{}) 

input := &s3.GetObjectInput { 
    Bucket: aws.String(defaultLocationRootBucket), 
    Key: aws.String(key), 
} 

n1, downloadError := downloader.Download(awsBuffer, input) 
if downloadError != nil { 
    loglib.Log(loglib.LevelError, applicationType, fmt.Sprintf("Failed to download from S3, file(%v) with error : %v.", key, downloadError)) 
    return 
} 


lenghts3:= int64(len(buffer.Bytes())) 

n2, bufferError := buffer.WriteAt(awsBuffer.Bytes(), lenghts3) 
if bufferError != nil { 
    loglib.Log(loglib.LevelError, applicationType, fmt.Sprintf("Failed to write to buffer, the file(%v) downloaded from S3 with error : %v.", key, bufferError)) 
} 

Répondre

0

Ce code:

lenghts3:= int64(len(buffer.Bytes())) 

Est-ce un concurrency problème: deux routines peuvent obtenir la longueur en même temps, obtenir la même position de départ, et les deux procéder à écrire dans le tampon avec la même position de départ, en marchant sur les orteils de l'autre. Etant donné que vous récupérez déjà des objets entiers en mémoire et que vous ne les diffusez pas dans le tampon combiné, vous pouvez tout simplement envoyer le contenu complet de chaque fichier sur un canal et demander à un récepteur de ce canal d'ajouter chaque résultat à un tampon octet partagé comme ils viennent, de manière synchrone.

+0

merci Adrian, ça a marché, vous aviez raison. – AthosPurple