code: @Nullable
    public static ImmutableWorkerInfo selectWorker(
        final Task task,
        final Map<String, ImmutableWorkerInfo> allWorkers,
        final WorkerTaskRunnerConfig workerTaskRunnerConfig,
        @Nullable final AffinityConfig affinityConfig,
        final Function<ImmutableMap<String, ImmutableWorkerInfo>, ImmutableWorkerInfo> workerSelector
    )
    {
      // Workers that could potentially run this task, ignoring affinityConfig.
      final Map<String, ImmutableWorkerInfo> runnableWorkers = allWorkers
          .values()
          .stream()
          .filter(worker -> worker.canRunTask(task)
                            && worker.isValidVersion(workerTaskRunnerConfig.getMinWorkerVersion()))
          .collect(Collectors.toMap(w -> w.getWorker().getHost(), Function.identity()));
  
      if (affinityConfig == null) {
        // All runnable workers are valid.
        return workerSelector.apply(ImmutableMap.copyOf(runnableWorkers));
      } else {
        // Workers assigned to the affinity pool for our task.
        final Set<String> dataSourceWorkers = affinityConfig.getAffinity().get(task.getDataSource());
  
        if (dataSourceWorkers == null) {
          // No affinity config for this dataSource; use non-affinity workers.
          return workerSelector.apply(getNonAffinityWorkers(affinityConfig, runnableWorkers));
        } else {
          // Get runnable, affinity workers.
          final ImmutableMap<String, ImmutableWorkerInfo> dataSourceWorkerMap =
              ImmutableMap.copyOf(Maps.filterKeys(runnableWorkers, dataSourceWorkers::contains));
  
          final ImmutableWorkerInfo selected = workerSelector.apply(dataSourceWorkerMap);
  
          if (selected != null) {
            return selected;
          } else if (affinityConfig.isStrong()) {
            return null;
          } else {
            // Weak affinity allows us to use nonAffinityWorkers for this dataSource, if no affinity workers
            // are available.
            return workerSelector.apply(getNonAffinityWorkers(affinityConfig, runnableWorkers));
          }
        }
      }
    }
docs: Helper for {@link WorkerSelectStrategy} implementations.
  
  @param allWorkers     map of all workers, in the style provided to {@link WorkerSelectStrategy}
  @param affinityConfig affinity config, or null
  @param workerSelector function that receives a list of eligible workers: version is high enough, worker can run
  the task, and worker satisfies the affinity config. may return null.
  
  @return selected worker from "allWorkers", or null.