What's up, on the backend there was an idea to transfer some functionality to the queue. What is meant:
-
We have a functional interface analogous to
Callable<?>
.@FunctionalInterface public interface QueueFunction<T, R> { T runq(R ... args); }
-
But a function can have multiple arguments, so I resorted to the barbaric
R... args
method. I was bitten by a pythonist at that moment. -
There is a
LinkedBlockingQueue<?>
queue, where, in theory, in place of the question mark should be my interfaceQueueFunction<T, R>
-
And when the call of the corresponding function with the marked annotation should happen, then (there is still a problem of how to intercept the call of this function in the spring there is
@Scheduled
I want something like that) I need to intercept this call and redirect it to the queue in order to call from the queue thread pool its implementation. -
I don't know how to poop ((((
A little about my research:
I tried to create a FutureTask<?>
implementation for myself, but now I can’t really enter how and what works there, I know the principle, but if you climb further along legacy, you can rip permanently.
There is an option to make an adapter for Runnable
, which hides Thread
.There is something similar in Legacy Java.
private static final class RunnableAdapter<T> implements Callable<T> {
private final Runnable task;
private final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
public String toString() {
return super.toString() + "[Wrapped task = " + task + "]";
}
}
Perhaps I have paws in this matter, and not enough skill. I am open to your suggestions :-*
Edition #1
I have a method:
@Queued(paramsCount = 3)
public String mergeInvoices(String acc_owner, String report_oid, String invoice_template_jr) throws IOException {
//do merge
}
It is a reflection of the QueueFunction<T,R>
, where R
are the arguments to this method and T
is the return value. There can be many such methods as in the example. And there can be different numbers of arguments. I want to annotate them with the number of parameters. And send this method for execution by a queue (so to speak). Execution by analogy with the annotation @Scheduled
(Spring/Micronaut), which sets the schedule. Perhaps there will be some other way.
But this function needs to be added to the execution queue. From the queue, it should be picked up by free threads and executed.
Example:
@EventListener
@Async
public void runQueues(final ServiceReadyEvent event) throws InterruptedException {
logger.info("starting queues...");
checkQueues(true);
for (int i = 0; i < workersCount; i++) {
(new Thread(this::runHouseCalc)).start();
logger.info("Run thread worker for House Calc " + i);
}
for (int i = 0; i < workersCount; i++) {
(new Thread(this::runInvCalc)).start();
logger.info("Run thread worker for Invoice Calc " + i);
}
}
private void runInvCalc() {
while (isRunning) {
MeHouseInvoiceQueue inv = null;
try {
functionsRepository.setUserId(suId);
inv = calcInvQueue.take();
functionsRepository.setInvoiceQueueStatus(inv.getId(), "processing", null, null, null, null);
long startSeed = new Date().getTime();
logger.info("event inv taken");
logger.info("oid = " + inv.getId() + " position: " + inv.getPosition() + " state: " + inv.getProcessing_status());
File file = reportsService.getFile(reportsService.getParametersForInvoices(inv));
long endSeed = new Date().getTime();
functionsRepository.setInvoiceQueueStatus(inv.getId(), "ready", file.getPath(), (int) Files.size(Path.of(file.getPath())), null, new SimpleDateFormat("HH:mm:ss").format(new Date((endSeed - startSeed)- 10800000L)));
} catch (Exception e) {
if (inv != null) functionsRepository.setInvoiceQueueStatus(inv.getId(), "ERROR", null, null, e.getMessage(), null);
logger.error(e.getMessage());
}
}
}
Aucun commentaire:
Enregistrer un commentaire