Cronjob parallele Ausführung

  • Hallo,


    ich habe einen kritischen Cronjob A. A darf nur 1x gleichzeitig alle 3 Minuten ausgeführt werden.
    Wenn allerdings 2 Forenbenutzer "gleichzeitig" das Forum betreten, wird Cronjob A 2x parallel ausgeführt. Das behindert die SQL-Arbeiten, die ausgeführt werden.
    Das ist mir irgendwie im Testforum passiert. Hinzuzufügen wäre dem noch, dass der Cronjob A eine etwa 10 sekündige Ausführungszeit hat.


    Ohne jetzt in den Source Code zu schauen: Wenn ein Cronjob auf "Running" gesetzt wird, wird dann eine weitere Instanz des Cronjob gestartet, wenn ein neuer User das Forum betritt? Das sieht für mich zumindest danach aus.


    VG
    Tobias

    • Official Post

    Cronjobs werden grundsätzlich vor dem Start als Running geflagged und erst dann ausgeführt, allerdings kann eine Race Condition nicht vollständig ausgeschlossen werden.


    Davon abgesehen: Bei sehr aufwändigen Cronjobs wäre es ggf. sinnvoller diese mit Hilfe echter Cronjobs auszuführen - sowohl um die periodische als auch vollständige Ausführung zu gewährleisten.

  • Das Problem kenne ich vom Plugin woltlab.com/pluginstore/file/1479/


    Unter bestimmten Umständen werden mehrere (in der Regel drei) gleichzeitige Ausführungen gestartet (wenn mehrere User online sind). Laut @UdoZ ist das Plugin aber so programmiert, dass das nicht passieren kann/darf. Somit scheint das WCF da irgendwie fehlerhaft zu sein (WCF 2.0 in meinem Fall).

  • Laut @UdoZ ist das Plugin aber so programmiert, dass das nicht passieren kann/darf

    Naja, das Plugin kann nicht verhindern, dass der Cronjob erneut getriggert wird. Und wenn das passiert, dann läuft der Cronjob halt mehr als 1x.
    Ich bin bisher davon ausgegangen, dass das WCF zuverlässig ein praktisch zeitgleiches, mehrfaches Triggern von Cronjobs verhindert.

    Gruß, Udo

  • Davon abgesehen: Bei sehr aufwändigen Cronjobs wäre es ggf. sinnvoller diese mit Hilfe echter Cronjobs auszuführen - sowohl um die periodische als auch vollständige Ausführung zu gewährleisten.

    Dafür fehlen einigen Kunden vermutlich die Rechte/Möglichkeiten am Server oder Webspace. Im Standardumfang eines Plugin möchte ich nicht davon ausgehen, dass jeder Benutzer Cronjobs einrichten kann.


    Ich habe mir auch schon überlegt die Tabelle zu locken und eine Transaktion zu starten.
    Allerdings arbeitet der Cronjob leider an häufig benutzten Tabellen, wie z.B. wcf1_user. Solange wäre dann beispielsweise keine Registrierung möglich...

  • Ich bin bisher davon ausgegangen, dass das WCF zuverlässig ein praktisch zeitgleiches, mehrfaches Triggern von Cronjobs verhindert.

    Im Prinzip meinte ich das mit meiner Aussage. ;)

  • Wenn ich mir den code so ansehe ist die einzige möglichkeit wie es dazu kommen kann die, dass mehrere cronjobs parallel ausgeführt werden sollen.
    Denn es wird nur einmalig beim laden aller cronjobs geprüft ob diese bereits ausgeführt werden und dann wird erst beim wirklichen ausführen eines cronjobs dieser als auszuführend markiert.
    Im grunde müsste beim aufruf der einzelnen Cronjobs nochmals geprüft werden ob sich der Status zwischenzeitlich eventuell geändert hat um das Problem zu umgehen...



    https://github.com/WoltLab/WCF…obScheduler.class.php#L57

    • Official Post

    @Morik In dieser Richtung gehen auch meine Gedanken.


    Im Prinzip wäre es ausreichend eine zusätzliche Datenbank-Spalte (z.B. executionHash VARCHAR(8)) anzulegen. Sobald ein Cronjob als anstehend ermittelt wird, wird ein SHA-1-Hash gebildet und die ersten 8 Zeichen zum befüllen der Spalte verwendet. Anschließend wird erneut der Cronjob per SELECT abgefragt und geschaut ob der Hash mit dem zuvor generierten Wert übereinstimmt. Wenn ja: Status auf Pending ändern und anschließend Cronjob ausführen, Wenn Nein: Ignorieren und mit dem nächsten weiter machen.