Schleife von anderer Methode stoppen? (Start continue)

beta20

Top Contributor
Hallo zusammen,

ich habe folgendes Szenario:

1) Innerhalb meinem @EJB - Container läuft ein Schedule
2) Er ruft zunächst aus der DB alle ausstehenden Aufträge ab
3) Anschließend wird über eine Schleife die Aufträge nacheinander abgearbeitet

Nun möchte ich aber eine "cancel" - Methode für den Schedule haben, die den derzeitigen Schleifendurchlauf beendet.
Ich möchte NICHT den Schedule komplett beendet, lediglich mit "continue" die nächste Iteration der Schleife starten.

Wie kann ich das machen?
 
Du hast einen Task, der mit einem EJB Timer periodisch ausgeführt wird. Dieser Task iteriert über Aufträge. Willst Du mit der cancel-Methode einen einzelnen Auftrag in der Schleife "übergehen" oder alle noch für diesen Task ausstehenden Aufträge (die würden bei der nächsten Ausführung des Tasks berücksichtigt)?
 
Hier mal ein Code Beispiel:

Java:
@Timeout
    @AccessTimeout(value = 20, unit = TimeUnit.MINUTES)
    @Schedule(minute = "*/1", hour = "*", persistent = false)
    public void execute() throws Exception {

            /**
             * Alle noch nicht ausgeführten Schedules bekommen
             */
            List<ScheduleExecution> scheduleExecutionList = scheduleExecutionService
                    .findAllScheduleExecutionOutstanding();
        
            for (ScheduleExecution scheduleExecution : scheduleExecutionList) {
                .....

Nun brauche ich eine Methode, die mir bei:
for (ScheduleExecution scheduleExecution : scheduleExecutionList) {
-> den aktuellen Durchlauf beendet...bzw.:
1) Das Objekt von scheduleExecution noch davor updated
scheduleExecution.setCanceled(true);
2) den Schleifendurchlauf beendet


cancel() {....}
 
Ich würde es mal wie folgt versuchen:
Java:
@Singleton
public class ... {
    private volatile boolean cancelled = false;

    public void cancel() {
        cancelled = true;
    }

    @Timeout
    @AccessTimeout(value = 20, unit = TimeUnit.MINUTES)
    @Schedule(minute = "*/1", hour = "*", persistent = false)
    public void execute() throws Exception {

        /**
         * Alle noch nicht ausgeführten Schedules bekommen
         */
        List<ScheduleExecution> scheduleExecutionList = scheduleExecutionService
                .findAllScheduleExecutionOutstanding();
        
        for (ScheduleExecution scheduleExecution : scheduleExecutionList) {
            if (!cancelled) {
                .....
            } else {
                scheduleExection.setCancelled(true);
            }
        }
        cancelled = false;
    }
 
der Code macht schon Sinn, und hatte ich auch schon überlegt es so zu machen.
Aber ich führe hier auch Methoden aus, die dann mehrere Minuten dauern können (Upload Files whatever).
Daher möchte ich SOFORT den Durchlauf beenden.
Any ideas?
 
Naja, das hängt davon ab, ob eine ScheduleExecution eine Methode für den Abbruch hat. Falls ja, könntest Du statt dem boolean eine Referenz auf die aktuelle ScheduleExecution setzen.
Java:
private ScheduleExecution currentExecution;

public void cancel() {
    if (currentExecution != null) {
        currentExecution.cancel();
    }
}

...
boolean cancelled = false;
for (ScheduleExection scheduleExecution : scheduleExecutionList) {
    if (!cancelled)
        currentExecution = scheduleExecution;
        scheduleExecution.run();
        cancelled = scheduleExecution.isCancelled();
    } else {
        scheduleExecution.setCancelled(true);
    }
}
EDIT: am Ende natürlich wieder auf null setzen.
 
achsooo.
Das hilft mir dann aber nur bedingt.
Wenn die fiktive Methode "run" aber 5 Min läuft, und gerade mal 3 Minuten davon vorüber sind, ich die Methode aber sofort abbrechen möchte, dann funktioniert das doch so nicht?
 
Ich zitiere mich:
das hängt davon ab, ob eine ScheduleExecution eine Methode für den Abbruch hat.

Die fiktive run() Methode muss schon so geschrieben sein, dass man sie prinzipiell abbrechen könnte. Wie genau das aussieht, hängt davon ab, was dort passiert. Im einfachsten Fall funktioniert das genauso wie oben (ein Flag, das in der run()-Methode abgeprüft wird und ggf. die Ausführung beendet).
 
Dann könntest Du versuchen, das in einen separaten Thread zu packen und diesen zusätzlich per interrupt() abzubrechen. Muss aber nicht funktionieren.
 
aktuell habe ich das Problem, dass innerhalb der Schleife ja nur eine Aktion ausgeführt werden kann, was natürlich nicht sein soll, da mehrere Aktionen auch parallel laufen sollen.

ich möchte gerne in einem EJB-Schedule gleichzeitig mehrere Aktionen / Prozesse ausführen.

Zum Hintergrund:

Ich habe in meiner Datenbank Aktionen eingeplant (Emailversand, ZIP-File generieren usw.).
Was ich mache:

a) Ich rufe erst mal aus der Datenbank ab, welche Aktionen denn gestartet werden können und speichere diese in eine Liste
b) Mittels einer Schleife führe ich diese aus.
-> Nun habe ich aber das Problem, dass ich so nur immer nur eine Aktion ausführen kann.
 
Besten Dank.

Sieht auf den ersten Blick genau nachdem aus, was ich brauche 🙂
Ich kenne zwar ein paar Klassen nicht (Future z.b.)
Werde es später ausprobieren...
Wenn ich die Anzahl an gleichzeitigen Aufgaben festlegen möchte, setze ich einfach eine Konstante anstatt 10, korrekt?
for (int i = 0; i < 10; i++) {
 

Zurück
Oben