Skip to content

Commit

Permalink
fix: Use custom thread factor class in SolverManager
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher-Chianelli committed Jun 11, 2024
1 parent 6452e8b commit bce9ba0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import ai.timefold.solver.core.api.solver.SolverStatus;
import ai.timefold.solver.core.api.solver.change.ProblemChange;
import ai.timefold.solver.core.config.solver.SolverManagerConfig;
import ai.timefold.solver.core.config.util.ConfigUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -47,7 +48,12 @@ public DefaultSolverManager(SolverFactory<Solution_> solverFactory,
this.solverFactory = solverFactory;
validateSolverFactory();
int parallelSolverCount = solverManagerConfig.resolveParallelSolverCount();
solverThreadPool = Executors.newFixedThreadPool(parallelSolverCount);
var threadFactory = Executors.defaultThreadFactory();
if (solverManagerConfig.getThreadFactoryClass() != null) {
threadFactory = ConfigUtils.newInstance(solverManagerConfig, "threadFactoryClass",
solverManagerConfig.getThreadFactoryClass());
}
solverThreadPool = Executors.newFixedThreadPool(parallelSolverCount, threadFactory);
problemIdToSolverJobMap = new ConcurrentHashMap<>(parallelSolverCount * 10);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -1010,4 +1011,36 @@ void terminateScheduledSolverJobEarly_returnsInputProblem() throws ExecutionExce
assertThat(result).isSameAs(inputProblem);
assertThat(solverJob.isTerminatedEarly()).isTrue();
}

public static class CustomThreadFactory implements ThreadFactory {
private static final String CUSTOM_THREAD_NAME = "CustomThread";

@Override
public Thread newThread(Runnable runnable) {
return new Thread(runnable, CUSTOM_THREAD_NAME);
}
}

@Test
@Timeout(60)
void threadFactoryIsUsed() throws ExecutionException, InterruptedException {
var threadCheckingPhaseConfig = new CustomPhaseConfig().withCustomPhaseCommands(
scoreDirector -> {
if (!Thread.currentThread().getName().equals(CustomThreadFactory.CUSTOM_THREAD_NAME)) {
fail("Custom thread factory not used");
}
});

var solverConfig = PlannerTestUtils.buildSolverConfig(TestdataSolution.class, TestdataEntity.class)
.withPhases(threadCheckingPhaseConfig, new ConstructionHeuristicPhaseConfig());

var solverManagerConfig = new SolverManagerConfig().withThreadFactoryClass(CustomThreadFactory.class);
solverManager = SolverManager.create(solverConfig, solverManagerConfig);

var inputProblem = PlannerTestUtils.generateTestdataSolution("s1", 4);
var solverJob = solverManager.solve(1L, inputProblem);

TestdataSolution result = solverJob.getFinalBestSolution();
assertThat(result).isNotNull();
}
}

0 comments on commit bce9ba0

Please sign in to comment.