code: func (deallocator *Deallocator) processService(ctx context.Context, service *api.Service) (bool, error) {
  	if !service.PendingDelete {
  		return false, nil
  	}
  
  	var (
  		tasks []*api.Task
  		err   error
  	)
  
  	deallocator.store.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 retrieve the list of tasks for service %v", service.ID)
  		// if in doubt, let's proceed to clean up the service anyway
  		// better to clean up resources that shouldn't be cleaned up yet
  		// than ending up with a service and some resources lost in limbo forever
  		return true, deallocator.deallocateService(ctx, service)
  	} else if len(tasks) == 0 {
  		// no tasks remaining for this service, we can clean it up
  		return true, deallocator.deallocateService(ctx, service)
  	}
  	deallocator.services[service.ID] = &serviceWithTaskCounts{service: service, taskCount: len(tasks)}
  	return false, nil
  }
docs: // if a service is marked for deletion, this checks whether it's ready to be
  // deleted yet, and does it if relevant