code: func SetServiceTasksRemove(ctx context.Context, s *store.MemoryStore, service *api.Service) {
  	var (
  		tasks []*api.Task
  		err   error
  	)
  	s.View(func(tx store.ReadTx) {
  		tasks, err = store.FindTasks(tx, store.ByServiceID(service.ID))
  	})
  	if err != nil {
  		log.G(ctx).WithError(err).Errorf("failed to list tasks")
  		return
  	}
  
  	err = s.Batch(func(batch *store.Batch) error {
  		for _, t := range tasks {
  			err := batch.Update(func(tx store.Tx) error {
  				// time travel is not allowed. if the current desired state is
  				// above the one we're trying to go to we can't go backwards.
  				// we have nothing to do and we should skip to the next task
  				if t.DesiredState > api.TaskStateRemove {
  					// log a warning, though. we shouln't be trying to rewrite
  					// a state to an earlier state
  					log.G(ctx).Warnf(
  						"cannot update task %v in desired state %v to an earlier desired state %v",
  						t.ID, t.DesiredState, api.TaskStateRemove,
  					)
  					return nil
  				}
  				// update desired state to REMOVE
  				t.DesiredState = api.TaskStateRemove
  
  				if err := store.UpdateTask(tx, t); err != nil {
  					log.G(ctx).WithError(err).Errorf("failed transaction: update task desired state to REMOVE")
  				}
  				return nil
  			})
  			if err != nil {
  				return err
  			}
  		}
  		return nil
  	})
  	if err != nil {
  		log.G(ctx).WithError(err).Errorf("task search transaction failed")
  	}
  }
docs: // SetServiceTasksRemove sets the desired state of tasks associated with a service
  // to REMOVE, so that they can be properly shut down by the agent and later removed
  // by the task reaper.