@@ -50,6 +50,8 @@ var uploadFingerprintCache = struct {
5050 m : map [string ]uploadFingerprintEntry {},
5151}
5252
53+ var uploadPathLocks sync.Map
54+
5355func ParsePairs (configured []string , defaultRemote string ) ([]Pair , error ) {
5456 if len (configured ) == 0 {
5557 return []Pair {{Local : "." , Remote : defaultRemote }}, nil
@@ -200,43 +202,47 @@ func syncUpPath(ctx context.Context, k Client, namespace, pod, podInstance strin
200202
201203 cacheKey := uploadFingerprintCacheKey (namespace , pod , p , excludes )
202204 if ! st .IsDir () {
203- fingerprint := fmt .Sprintf ("file:%d:%d" , st .Size (), st .ModTime ().UnixNano ())
204- if ! force && uploadFingerprintMatches (cacheKey , podInstance , fingerprint ) {
205- return pathStats {Skipped : true }, nil
206- }
207- if err := k .CopyToPod (ctx , namespace , absLocal , pod , p .Remote ); err != nil {
208- return pathStats {}, err
209- }
210- setUploadFingerprint (cacheKey , podInstance , fingerprint )
211- return pathStats {UploadBytes : st .Size ()}, nil
205+ return withUploadKeyLock (cacheKey , func () (pathStats , error ) {
206+ fingerprint := fmt .Sprintf ("file:%d:%d" , st .Size (), st .ModTime ().UnixNano ())
207+ if ! force && uploadFingerprintMatches (cacheKey , podInstance , fingerprint ) {
208+ return pathStats {Skipped : true }, nil
209+ }
210+ if err := k .CopyToPod (ctx , namespace , absLocal , pod , p .Remote ); err != nil {
211+ return pathStats {}, err
212+ }
213+ setUploadFingerprint (cacheKey , podInstance , fingerprint )
214+ return pathStats {UploadBytes : st .Size ()}, nil
215+ })
212216 }
213217
214218 fingerprint , err := localDirFingerprint (absLocal , excludes )
215219 if err != nil {
216220 return pathStats {}, err
217221 }
218- if ! force && uploadFingerprintMatches (cacheKey , podInstance , fingerprint ) {
219- return pathStats {Skipped : true }, nil
220- }
222+ return withUploadKeyLock (cacheKey , func () (pathStats , error ) {
223+ if ! force && uploadFingerprintMatches (cacheKey , podInstance , fingerprint ) {
224+ return pathStats {Skipped : true }, nil
225+ }
221226
222- stream , waitTar , err := startLocalTarStream (ctx , absLocal , excludes )
223- if err != nil {
224- return pathStats {}, err
225- }
226- defer stream .Close ()
227+ stream , waitTar , err := startLocalTarStream (ctx , absLocal , excludes )
228+ if err != nil {
229+ return pathStats {}, err
230+ }
231+ defer stream .Close ()
227232
228- countingStream := & countingReader {Reader : stream }
229- if err := k .ExtractTarToPod (ctx , namespace , pod , p .Remote , countingStream ); err != nil {
230- if tarErr := waitTar (); tarErr != nil {
231- return pathStats {}, tarErr
233+ countingStream := & countingReader {Reader : stream }
234+ if err := k .ExtractTarToPod (ctx , namespace , pod , p .Remote , countingStream ); err != nil {
235+ if tarErr := waitTar (); tarErr != nil {
236+ return pathStats {}, tarErr
237+ }
238+ return pathStats {}, err
232239 }
233- return pathStats {}, err
234- }
235- if err := waitTar (); err != nil {
236- return pathStats {}, err
237- }
238- setUploadFingerprint (cacheKey , podInstance , fingerprint )
239- return pathStats {UploadBytes : countingStream .BytesRead ()}, nil
240+ if err := waitTar (); err != nil {
241+ return pathStats {}, err
242+ }
243+ setUploadFingerprint (cacheKey , podInstance , fingerprint )
244+ return pathStats {UploadBytes : countingStream .BytesRead ()}, nil
245+ })
240246}
241247
242248func syncDownPath (ctx context.Context , k Client , namespace , pod string , p Pair , excludes []string ) (pathStats , error ) {
@@ -436,6 +442,14 @@ func uploadFingerprintCacheLen() int {
436442 return len (uploadFingerprintCache .m )
437443}
438444
445+ func withUploadKeyLock (key string , fn func () (pathStats , error )) (pathStats , error ) {
446+ v , _ := uploadPathLocks .LoadOrStore (key , & sync.Mutex {})
447+ mu := v .(* sync.Mutex )
448+ mu .Lock ()
449+ defer mu .Unlock ()
450+ return fn ()
451+ }
452+
439453func localDirFingerprint (root string , excludes []string ) (string , error ) {
440454 var files int64
441455 var bytes int64
0 commit comments