code: func (p *Pod) WaitFinished(ctx context.Context) error {
  	f := func() bool {
  		switch err := p.TrySharedLock(); err {
  		case nil:
  			// the pod is now locked successfully, hence one of the running phases passed.
  			// continue with unlocking the pod immediately below.
  		case lock.ErrLocked:
  			// pod is still locked, hence we are still in a running phase.
  			// i.e. in pepare, run, exitedGarbage, garbage state.
  			return false
  		default:
  			// some error occurred, bail out.
  			return true
  		}
  
  		// unlock immediately
  		if err := p.Unlock(); err != nil {
  			return true
  		}
  
  		if err := p.refreshState(); err != nil {
  			return true
  		}
  
  		// if we're in the gap between preparing and running in a split prepare/run-prepared usage, take a nap
  		if p.isPrepared {
  			time.Sleep(time.Second)
  		}
  
  		return p.IsFinished()
  	}
  
  	return retry(ctx, f, 100*time.Millisecond)
  }
docs: // WaitFinished waits for a pod to finish by polling every 100 milliseconds
  // or until the given context is cancelled. This method refreshes the pod state.
  // It is the caller's responsibility to determine the actual terminal state.