.
This commit is contained in:
parent
c65d88f645
commit
015c7ca24b
5 changed files with 25 additions and 8 deletions
|
|
@ -6,6 +6,7 @@ import org.springframework.boot.context.properties.bind.DefaultValue;
|
||||||
|
|
||||||
public record PipelineSettings(
|
public record PipelineSettings(
|
||||||
@DefaultValue("5000") Integer subjectBatchSize,
|
@DefaultValue("5000") Integer subjectBatchSize,
|
||||||
|
@DefaultValue("3") Integer saveSubjectStageConcurrency,
|
||||||
@DefaultValue("15") Integer nameEnricherStageConcurrency,
|
@DefaultValue("15") Integer nameEnricherStageConcurrency,
|
||||||
@DefaultValue("10") Integer idEnricherStageConcurrency,
|
@DefaultValue("10") Integer idEnricherStageConcurrency,
|
||||||
@DefaultValue("5") Integer errorAttemptCount,
|
@DefaultValue("5") Integer errorAttemptCount,
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ public class PipelinePackageManager {
|
||||||
this.fidNameEnricher = fidNameEnricher;
|
this.fidNameEnricher = fidNameEnricher;
|
||||||
this.creditTrackerSettings = creditTrackerSettings;
|
this.creditTrackerSettings = creditTrackerSettings;
|
||||||
this.semaphore = new Semaphore(creditTrackerSettings.getPipeline().parallelRequests());
|
this.semaphore = new Semaphore(creditTrackerSettings.getPipeline().parallelRequests());
|
||||||
|
log.info("pipeline settings: {}", creditTrackerSettings.getPipeline());
|
||||||
this.pipelineBackoff = pipelineBackoff;
|
this.pipelineBackoff = pipelineBackoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,6 +88,7 @@ public class PipelinePackageManager {
|
||||||
throw new RuntimeException("Too many concurrent requests");
|
throw new RuntimeException("Too many concurrent requests");
|
||||||
}
|
}
|
||||||
log.info("throttler permits after acquire: {}", semaphore.availablePermits());
|
log.info("throttler permits after acquire: {}", semaphore.availablePermits());
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
Pipeline pipeline = PipeLineBuilderV2.first(saveSubjectQueueFactory.getObject(), idEnricherQueueFactory.getObject())
|
Pipeline pipeline = PipeLineBuilderV2.first(saveSubjectQueueFactory.getObject(), idEnricherQueueFactory.getObject())
|
||||||
.handler(saveSubjectHandler)
|
.handler(saveSubjectHandler)
|
||||||
|
|
@ -110,6 +112,8 @@ public class PipelinePackageManager {
|
||||||
.orTimeout(creditTrackerSettings.getPipeline().globalTimeout().toMillis(), TimeUnit.MILLISECONDS)
|
.orTimeout(creditTrackerSettings.getPipeline().globalTimeout().toMillis(), TimeUnit.MILLISECONDS)
|
||||||
.whenComplete((v, e) -> {
|
.whenComplete((v, e) -> {
|
||||||
try {
|
try {
|
||||||
|
long finishTime = System.currentTimeMillis();
|
||||||
|
log.info("pipeline time passed: {} ms", finishTime - startTime);
|
||||||
if (e instanceof XmlMergeCoordinator.PipelineTerminatorException) {
|
if (e instanceof XmlMergeCoordinator.PipelineTerminatorException) {
|
||||||
log.info("when complete: terminator was interrupted.");
|
log.info("when complete: terminator was interrupted.");
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import java.util.List;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
@ -13,8 +13,8 @@ import java.util.function.Consumer;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import ru.nbch.credit_tracker.model.StagePayload;
|
import ru.nbch.credit_tracker.model.StagePayload;
|
||||||
import ru.nbch.credit_tracker.utils.TaskTimer;
|
|
||||||
import ru.nbch.credit_tracker.utils.LogUtil;
|
import ru.nbch.credit_tracker.utils.LogUtil;
|
||||||
|
import ru.nbch.credit_tracker.utils.TaskTimer;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class Stage<X extends StagePayload, Z extends StagePayload> implements Runnable {
|
public class Stage<X extends StagePayload, Z extends StagePayload> implements Runnable {
|
||||||
|
|
@ -42,10 +42,11 @@ public class Stage<X extends StagePayload, Z extends StagePayload> implements Ru
|
||||||
this.out = out;
|
this.out = out;
|
||||||
this.dispatcherName = dispatcher.getClass().getSimpleName();
|
this.dispatcherName = dispatcher.getClass().getSimpleName();
|
||||||
var mdcMap = LogUtil.extractMdcMap();
|
var mdcMap = LogUtil.extractMdcMap();
|
||||||
|
BlockingQueue<Runnable> handoffQueue = new SynchronousQueue<>();
|
||||||
this.ioPool = new ThreadPoolExecutor(dispatcher.preferredConcurrency(),
|
this.ioPool = new ThreadPoolExecutor(dispatcher.preferredConcurrency(),
|
||||||
dispatcher.preferredConcurrency(),
|
dispatcher.preferredConcurrency(),
|
||||||
0L, TimeUnit.MINUTES,
|
0L, TimeUnit.MINUTES,
|
||||||
new LinkedBlockingQueue<>(1),
|
handoffQueue,
|
||||||
r -> {
|
r -> {
|
||||||
Thread t = new Thread(LogUtil.wrap(mdcMap, r));
|
Thread t = new Thread(LogUtil.wrap(mdcMap, r));
|
||||||
t.setName("pipe-handler-%s-%d".formatted(dispatcherName, t.threadId()));
|
t.setName("pipe-handler-%s-%d".formatted(dispatcherName, t.threadId()));
|
||||||
|
|
@ -53,7 +54,13 @@ public class Stage<X extends StagePayload, Z extends StagePayload> implements Ru
|
||||||
},
|
},
|
||||||
(r, executor) -> {
|
(r, executor) -> {
|
||||||
log.info("stage {}: all threads are working; switch to CallerRunsPolicy", dispatcherName);
|
log.info("stage {}: all threads are working; switch to CallerRunsPolicy", dispatcherName);
|
||||||
callerRunsPolicy.rejectedExecution(r, executor);
|
try {
|
||||||
|
//блокировать отправителя, пока какой‑то рабочий поток не возьмёт задачу
|
||||||
|
handoffQueue.put(r);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
// callerRunsPolicy.rejectedExecution(r, executor);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +86,6 @@ public class Stage<X extends StagePayload, Z extends StagePayload> implements Ru
|
||||||
}
|
}
|
||||||
f.get();
|
f.get();
|
||||||
}
|
}
|
||||||
log.trace("Stage time stats: {}", stopWatch.info());
|
|
||||||
dispatcher.handleOnPoison(b);
|
dispatcher.handleOnPoison(b);
|
||||||
putQuiet(out, dispatcher.cookPoison());
|
putQuiet(out, dispatcher.cookPoison());
|
||||||
log.info("stage {} finished.", dispatcherName);
|
log.info("stage {} finished.", dispatcherName);
|
||||||
|
|
@ -97,7 +103,7 @@ public class Stage<X extends StagePayload, Z extends StagePayload> implements Ru
|
||||||
}
|
}
|
||||||
log.info("stage {} task {} started.", dispatcher.getClass().getSimpleName(), finalCounter);
|
log.info("stage {} task {} started.", dispatcher.getClass().getSimpleName(), finalCounter);
|
||||||
Z p;
|
Z p;
|
||||||
try (var m = stopWatch.start(dispatcherName)){
|
try (var m = stopWatch.start(dispatcherName + "-handler")){
|
||||||
p = dispatcher.handle(b);
|
p = dispatcher.handle(b);
|
||||||
}
|
}
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
|
|
@ -159,6 +165,7 @@ public class Stage<X extends StagePayload, Z extends StagePayload> implements Ru
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
log.info("Stage {} is getting shutdown", dispatcher.getClass().getSimpleName());
|
log.info("Stage {} is getting shutdown", dispatcher.getClass().getSimpleName());
|
||||||
|
log.trace("Stage time stats: {}", stopWatch.info());
|
||||||
ioPool.shutdownNow(); // прерываем обработчики
|
ioPool.shutdownNow(); // прерываем обработчики
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ public class SaveSubjectHandler implements Handler<SubjectPayload, SubjectPayloa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int preferredConcurrency() {
|
public int preferredConcurrency() {
|
||||||
return 20;
|
return creditTrackerSettings.getPipeline().saveSubjectStageConcurrency();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.model.impl.PartFilePayload;
|
import ru.nbch.credit_tracker.model.impl.PartFilePayload;
|
||||||
import ru.nbch.credit_tracker.model.impl.SignalXmlFilePayload;
|
import ru.nbch.credit_tracker.model.impl.SignalXmlFilePayload;
|
||||||
import ru.nbch.credit_tracker.service.task.setup.IPipeLineTerminator;
|
import ru.nbch.credit_tracker.service.task.setup.IPipeLineTerminator;
|
||||||
|
import ru.nbch.credit_tracker.utils.TaskTimer;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public final class XmlMergeCoordinator implements IPipeLineTerminator<PartFilePayload, SignalXmlFilePayload> {
|
public final class XmlMergeCoordinator implements IPipeLineTerminator<PartFilePayload, SignalXmlFilePayload> {
|
||||||
|
|
@ -29,6 +30,7 @@ public final class XmlMergeCoordinator implements IPipeLineTerminator<PartFilePa
|
||||||
private Path out;
|
private Path out;
|
||||||
private final CreditTrackerSettings config;
|
private final CreditTrackerSettings config;
|
||||||
private BlockingQueue<PartFilePayload> inQueue;
|
private BlockingQueue<PartFilePayload> inQueue;
|
||||||
|
private final TaskTimer stopWatch = new TaskTimer();
|
||||||
|
|
||||||
public XmlMergeCoordinator(CreditTrackerSettings config) {
|
public XmlMergeCoordinator(CreditTrackerSettings config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
@ -45,9 +47,12 @@ public final class XmlMergeCoordinator implements IPipeLineTerminator<PartFilePa
|
||||||
if (part.isPoison()) {
|
if (part.isPoison()) {
|
||||||
log.debug("Got poison");
|
log.debug("Got poison");
|
||||||
done.complete(new SignalXmlFilePayload(out));
|
done.complete(new SignalXmlFilePayload(out));
|
||||||
|
log.info("Stage time stats: {}", stopWatch.info());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
try (var m = stopWatch.start("XmlMergeCoordinator")) {
|
||||||
mergeBatch(part);
|
mergeBatch(part);
|
||||||
|
}
|
||||||
} catch (InterruptedException ie) {
|
} catch (InterruptedException ie) {
|
||||||
log.info("pipeline terminator was interrupted!");
|
log.info("pipeline terminator was interrupted!");
|
||||||
done.completeExceptionally(new PipelineTerminatorException());
|
done.completeExceptionally(new PipelineTerminatorException());
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue