Cronjob

  • Affected App
    WoltLab Suite Core

    Hallo,
    ich benutze noch das WCF 2.0 und kann wegen Inkompatibilität nicht aufs WCF 2.1 updaten. Deswegen weiß ich nicht ob der Fehler schon behoben wurde. :rolleyes:



    Ich habe einen Cronjob, der alle Produktinformationen anhand einer externen Source updatet. Bei manueller Ausführung im ACP funktioniert er zu 100% und dauert etwa 10 Sekunden.
    Wenn der Cronjob im Frontend durch einen User ausgeführt wird, dann ist die Chance etwa 50/50, dass dann im Log erfolgreich steht. Der Log ist mir auch egal, aber der Cronjob deaktiviert sich irgendwann von selbst.
    Das ist ungünstig, weil die Produktupdates sehr wichtig sind.
    Woran liegt das?

    • Official Post

    aber der Cronjob deaktiviert sich irgendwann von selbst.
    Das ist ungünstig, weil die Produktupdates sehr wichtig sind.
    Woran liegt das?

    Wenn die Ausführung eines Cronjobs dreimal hintereinander fehlgeschlagen ist, wird er automatisch deaktiviert. Sollte er danach aber erfolgreich manuell ausgeführt werden, wird er wieder aktiviert.

  • Okay, das dachte ich mir schon. Ich habe aber keine Exceptions o.ä. im Protokoll. Wieso wird dann der Cronjob "nicht erfolgreich" ausgeführt?
    Wenn ich ihn manuell im ACP ausführe, funktioniert er auch.

  • Gute Idee. Nachdem ich das error Logging eingeschaltet habe:

    Quote

    2015/03/03 20:50:47 [error] 24353#0: *246564 FastCGI sent in stderr: "PHP message: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 48 bytes) in /var/www/virtual/xxx/htdocs/wcf/lib/system/database/statement/PreparedStatement.class.php on line 92" while reading response header from upstream, client: 178.27.123.233, server: www.xxx.de, request: "POST /ajax-proxy/? HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm/www.xxx.de.socket:", host: "www.xxxx.de"

    Nur komisch, dass er genug Speicher hat, wenn ich den Cronjob im ACP ausführe.

    • Official Post

    Nicht direkt, du kannst dir aber ein kurzes PHP-Skript schreiben, dass dies macht, es ist im Prinzip nur der API-Aufruf \wcf\data\cronjob\CronjobAction::executeCronjobs().


    Wenn du den Cronjob aber eh nur via echtem cronjob ausführen möchtest, wäre es sinnvoller dies direkt in eine eigene PHP-Datei auszulagern die du dann anschließend ausführst. Andernfalls bleibt das Problem, dass auch Besucher die Ausführung auslösen können, aber genau das möchtet du ja eher nicht.

  • Hi,




    erstmal danke fuer den Tip mit der API, echte Cronjobs waere vorteilhafter, gerade wenn nachts kaum user online sind werden einige dinge halt nicht ausgefuehrt oder erst nachdem der erste user sich eingelogged hat, etwas unschoen, aber ok.



    Ich hab aber mal den tip mit der API probiert, bekommen aber eine fehler meldung:


    mein php script:

    PHP
    <?php
    require_once('./global.php');
    wcf\data\cronjob\CronjobAction::executeCronjobs();
    ?>

    Fehlermeldung:


    Message: PHP error in file /var/www/upload/cronjob-workaround.php (4): Non-static method wcf\data\cronjob\CronjobAction::executeCronjobs() should not be called statically
    File: /var/www/wbb4/upload/wcf/lib/system/WCF.class.php (304)
    PHP version: 5.5.9
    WCF version: 2.1.2 pl 4 (Typhoon)
    Request URI: /upload/cronjob-workaround.php
    Referrer:
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
    Information: ""
    Stacktrace:
    #0 /var/www/wbb4/upload/cronjob-workaround.php(4): wcf\system\WCF::handleError(2048, 'Non-static meth...', '/var/www/WBB...', 4, Array)
    #1 /var/www/wbb4/upload/cronjob-workaround.php(4): wcf\data\cronjob\CronjobAction::executeCronjobs()
    #2 {main}




    Wenn hier einer ne loesung hat die mir weiterhilft waere ich seh dankbar.



    Interresant waere es wenn man Jobs einzeln ausfuehren koennte z.b. alle x minuten "SessionCleanUpCronjob" und alle xx minuten "LastActivityCronjob"
    Wobei der interval ja via (*nix)Cronjob kommt, waere halt nur der API call entsprechend.

  • Nochmals Danke fuer die schnelle und hilfreiche Antwort, funktioniert wie gewuenscht!


    Einen kleinen negativen/unschoenen Nebeneffekt hat es nur, da der cronjob bei uns minuetlich ausgefuehrt wird, haben wir nun jede minute (Benutzer-online timeout = 900s) eine Gast in der Benutzer-Online Anzeige ohne IP etc. und durch den gesetzten Timeout summiert sich das, kann man das irgendwie umgehen ohne die Anzeige der unregistrierten Benutzer abzuschalten ?

  • wenn es alle 15mins liefe wuerde die 5mins cronjobs z.b. nicht ausgefuehrt automatisch (wenn kein benutzer online). Deine Frage ist aber irrelevant fuer das problem, den wenn ich mein Benutzer-online timout auf 3600 stell haette ich trotzdem 4 Gaeste ohne IP bei einem 15m interval , es verschiebt nur das problem, loest es aber nicht ;)

    • Official Post

    wenn es alle 15mins liefe wuerde die 5mins cronjobs z.b. nicht ausgefuehrt automatisch (wenn kein benutzer online).

    Falsch. Die 5 Minuten Cronjobs würden dann lediglich "verspätet" ausgeführt werden, was, normalerweise, irrelevant ist, wenn soweiso keiner online ist.


    Deine Frage ist aber irrelevant fuer das problem, den wenn ich mein Benutzer-online timout auf 3600 stell haette ich trotzdem 4 Gaeste ohne IP bei einem 15m interval , es verschiebt nur das problem, loest es aber nicht

    Du musst lediglich dafür sorgen, dass das Skript immer für die gleiche WCF-Session ausgeführt wird. Du könntest bspw. deine SessionID in einer Textdatei (oder in einer anderen Session, oder wie auch immer) speichern und in der Datei immer wieder benutzen.

  • Falsch. Die 5 Minuten Cronjobs würden dann lediglich "verspätet" ausgeführt werden, was, normalerweise, irrelevant ist, wenn soweiso keiner online ist.

    Genau das war mein eingangs problem, das wenn keiner online ist die entsprechenden jobs nicht ausgefuehrt werden, ist aber ein muss fuer diverse dinge im hintergrund.


    Du musst lediglich dafür sorgen, dass das Skript immer für die gleiche WCF-Session ausgeführt wird. Du könntest bspw. deine SessionID in einer Textdatei (oder in einer anderen Session, oder wie auch immer) speichern und in der Datei immer wieder benutzen.

    Ok, das waere nen versuch wert, nur mach ich ja nen API call aufs WCF (siehe oben) und stoesste die abfrage an ob ein job ansteht, da stellt sich mir die frage wie ich da die session mit uebergeben kann.
    Ich bin leider noch nicht so im wbb4.x/wcf drinn wie ich gerne wuerde, da wir gerade erst vom alten 2.3.6 dahin migrieren werden.



    alternativ kam mir die idee, das ich auch einfach bei jedem cronjob aufruf auf die entsprechende requestURI filtern kann in der wcf_session tabelle und einfach deleten.

    • Official Post

    Genau das war mein eingangs problem, das wenn keiner online ist die entsprechenden jobs nicht ausgefuehrt werden, ist aber ein muss fuer diverse dinge im hintergrund.

    Jobs werden immer ausgeführt. Allerdings u.U. nicht fristgerecht. Spätestens dann, wenn der Cronjob ausgeführt wird, werden alte Jobs auch nachgeholt. Für welche Dinge im Hintergrund ist es den ein muss? Nichts WCF internes, dort würde es auch reichen, wenn du die nur alle 15 Minuten anstößt.


    Ok, das waere nen versuch wert, nur mach ich ja nen API call aufs WCF (siehe oben) und stoesste die abfrage an ob ein job ansteht, da stellt sich mir die frage wie ich da die session mit uebergeben kann.
    Ich bin leider noch nicht so im wbb4.x/wcf drinn wie ich gerne wuerde, da wir gerade erst vom alten 2.3.6 dahin migrieren werden.


    Du könntest bspw. den GET-Wert manipulieren, bevor du die global.php aufrufst. Dieser dürfte, normalerweise, ja nicht gesetzt sein.

  • Müsste man nicht die WCFCLI verwenden können ?

    Ich glaub, das war ein guter tipp, noch garnicht entdeckt die cli :)
    cron´s via cli erzeugen zumindest keine session, und user/PW laesst sich ja schoen pipen (echo -e "USER\rPASSl\rcronjob execute" | php cli.php) ;)



    Danke euch beiden fuer die tipps.

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!