code: func (w *tableWorker) pickAndExecTask(ctx context.Context) {
  	var task *lookupTableTask
  	var ok bool
  	defer func() {
  		if r := recover(); r != nil {
  			buf := make([]byte, 4096)
  			stackSize := runtime.Stack(buf, false)
  			buf = buf[:stackSize]
  			logutil.Logger(ctx).Error("tableWorker in IndexLookUpExecutor panicked", zap.String("stack", string(buf)))
  			task.doneCh <- errors.Errorf("%v", r)
  		}
  	}()
  	for {
  		// Don't check ctx.Done() on purpose. If background worker get the signal and all
  		// exit immediately, session's goroutine doesn't know this and still calling Next(),
  		// it may block reading task.doneCh forever.
  		select {
  		case task, ok = <-w.workCh:
  			if !ok {
  				return
  			}
  		case <-w.finished:
  			return
  		}
  		err := w.executeTask(ctx, task)
  		task.doneCh <- err
  	}
  }
docs: // pickAndExecTask picks tasks from workCh, and execute them.