func (s *Sync) Start(st Stream) error { s.waitForContainer() if !filepath.IsAbs(s.Remote) { wdb, err := Docker("inspect", "--format", "'{{.Config.WorkingDir}}'", s.Container).Output() if err != nil { return err } swdb := string(wdb) swdb = strings.TrimSpace(swdb) swdb = strings.TrimPrefix(swdb, "'") swdb = strings.TrimSuffix(swdb, "'") s.Remote = filepath.Join(swdb, s.Remote) } go s.watchIncoming(st) go s.watchOutgoing(st) incoming := []changes.Change{} outgoing := []changes.Change{} for { timeout := time.After(1 * time.Second) select { case c := <-s.incoming: incoming = append(incoming, c) case c := <-s.outgoing: outgoing = append(outgoing, c) case <-timeout: if len(incoming) > 0 { a, r := changes.Partition(incoming) s.syncIncomingAdds(a, st) s.syncIncomingRemoves(r, st) incoming = []changes.Change{} } if len(outgoing) > 0 { a, r := changes.Partition(outgoing) s.syncOutgoingAdds(a, st) s.syncOutgoingRemoves(r, st) outgoing = []changes.Change{} } } } return nil }
func (s *Sync) syncIncoming(st Stream) { defer s.lock.Unlock() s.lock.Lock() if len(s.incoming) == 0 { return } adds, removes := changes.Partition(s.incoming) s.syncIncomingAdds(adds, st) s.syncIncomingRemoves(removes, st) s.incoming = nil }
func (s *Sync) syncOutgoing(st Stream) { defer s.lock.Unlock() s.lock.Lock() if len(s.outgoing) == 0 { return } keys := make([]changes.Change, 0) for k := range s.outgoing { keys = append(keys, k) } adds, removes := changes.Partition(keys) s.syncOutgoingAdds(adds, st) s.syncOutgoingRemoves(removes, st) s.outgoing = make(map[changes.Change]bool) }