71 lines
2.5 KiB
TypeScript
71 lines
2.5 KiB
TypeScript
import EvolutionWorker from './evolution.worker?worker';
|
|
import type { Population, Individual } from './evolution';
|
|
import type { EvolutionConfig } from './types';
|
|
|
|
export class WorkerPool {
|
|
private workers: Worker[] = [];
|
|
private poolSize: number;
|
|
|
|
constructor(size: number = navigator.hardwareConcurrency || 4) {
|
|
this.poolSize = size;
|
|
for (let i = 0; i < size; i++) {
|
|
this.workers.push(new EvolutionWorker());
|
|
}
|
|
}
|
|
|
|
terminate() {
|
|
this.workers.forEach(w => w.terminate());
|
|
this.workers = [];
|
|
}
|
|
|
|
async evaluateParallel(population: Population, config: EvolutionConfig): Promise<Population> {
|
|
// Split individuals into chunks
|
|
const chunkSize = Math.ceil(population.individuals.length / this.poolSize);
|
|
const chunks: Individual[][] = [];
|
|
|
|
for (let i = 0; i < population.individuals.length; i += chunkSize) {
|
|
chunks.push(population.individuals.slice(i, i + chunkSize));
|
|
}
|
|
|
|
// Dispatch chunks to workers
|
|
const promises = chunks.map((chunk, index) => {
|
|
return new Promise<Individual[]>((resolve, reject) => {
|
|
const worker = this.workers[index];
|
|
|
|
// One-time listener for this request
|
|
const handler = (e: MessageEvent) => {
|
|
if (e.data.type === 'EVAL_RESULT') {
|
|
worker.removeEventListener('message', handler);
|
|
resolve(e.data.payload);
|
|
} else if (e.data.type === 'ERROR') {
|
|
worker.removeEventListener('message', handler);
|
|
reject(e.data.payload);
|
|
}
|
|
};
|
|
|
|
worker.addEventListener('message', handler);
|
|
|
|
worker.postMessage({
|
|
type: 'EVALUATE_ONLY',
|
|
payload: {
|
|
individuals: chunk,
|
|
config
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
// Wait for all chunks
|
|
const results = await Promise.all(promises);
|
|
|
|
// Merge results
|
|
const mergedIndividuals = results.flat();
|
|
|
|
// Reconstruct population with evaluated individuals
|
|
return {
|
|
...population,
|
|
individuals: mergedIndividuals
|
|
};
|
|
}
|
|
}
|