chooseType typeChooser
client APIClient
- auth *arvados.APIClientAuthorization
- current map[string]QueueEnt
- updated time.Time
- mtx sync.Mutex
- keeplocal map[string]struct{}
+ auth *arvados.APIClientAuthorization
+ current map[string]QueueEnt
+ updated time.Time
+ mtx sync.Mutex
+
+ // Methods that modify the Queue (like Lock) add the affected
+ // container UUIDs to dontupdate. When applying a batch of
+ // updates received from the network, anything appearing in
+ // dontupdate is skipped, in case the received update has
+ // already been superseded by the locally initiated change.
+ // When no network update is in progress, this protection is
+ // not needed, and dontupdate is nil.
+ dontupdate map[string]struct{}
}
// NewQueue returns a new Queue. When a new container appears in the
// containers.
func (cq *Queue) Update() error {
cq.mtx.Lock()
- cq.keeplocal = map[string]struct{}{}
+ cq.dontupdate = map[string]struct{}{}
updateStarted := time.Now()
cq.mtx.Unlock()
cq.mtx.Lock()
defer cq.mtx.Unlock()
for uuid, ctr := range next {
- if _, keep := cq.keeplocal[uuid]; keep {
+ if _, keep := cq.dontupdate[uuid]; keep {
continue
}
if cur, ok := cq.current[uuid]; !ok {
}
}
for uuid := range cq.current {
- if _, keep := cq.keeplocal[uuid]; keep {
+ if _, keep := cq.dontupdate[uuid]; keep {
continue
} else if _, keep = next[uuid]; keep {
continue
delete(cq.current, uuid)
}
}
- cq.keeplocal = nil
+ cq.dontupdate = nil
cq.updated = updateStarted
return nil
}
cq.mtx.Lock()
defer cq.mtx.Unlock()
- if cq.keeplocal != nil {
- cq.keeplocal[uuid] = struct{}{}
+ if cq.dontupdate != nil {
+ cq.dontupdate[uuid] = struct{}{}
}
if ent, ok := cq.current[uuid]; !ok {
cq.addEnt(uuid, resp)