Example #1
0
func doSyncCmdSession(bar barSend, s *sessionV1) <-chan syncSession {
	ssCh := make(chan syncSession)
	// Separate source and target. 'sync' can take only one source.
	// but any number of targets, even the recursive URLs mixed in-between.
	sourceURL := s.URLs[0] // first one is source
	targetURLs := s.URLs[1:]

	go func(sourceURL string, targetURLs []string, bar barSend, ssCh chan syncSession, s *sessionV1) {
		defer close(ssCh)
		go trapSync(ssCh)

		var lock countlock.Locker
		if !globalQuietFlag {
			// Keep progress-bar and copy routines in sync.
			lock = countlock.New()
			defer lock.Close()
		}

		wg := new(sync.WaitGroup)
		syncQueue := make(chan bool, int(math.Max(float64(runtime.NumCPU())-1, 1)))
		defer close(syncQueue)

		go doPrepareSyncURLs(sourceURL, targetURLs, bar, lock)

		for sURLs := range prepareSyncURLs(sourceURL, targetURLs) {
			if sURLs.Error != nil {
				ssCh <- syncSession{
					Error: iodine.New(sURLs.Error, nil),
					Done:  false,
				}
				continue
			}
			syncQueue <- true
			wg.Add(1)
			if !globalQuietFlag {
				lock.Down() // Do not jump ahead of the progress bar builder above.
			}
			go doSyncSession(sURLs, &bar, syncQueue, ssCh, wg, s)
		}
		wg.Wait()
	}(sourceURL, targetURLs, bar, ssCh, s)
	return ssCh
}