PHP en periodieke cronjob

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • skate master
  • Registratie: September 2004
  • Laatst online: 12:02

skate master

Autodesk Educator Expert

Topicstarter
Mensen,

voor de vereniging heb ik een website gemaakt waarin voor verschillende wedstrijden / evenementen de vrijwilligers gepland kunnen worden.

achtergrond
Via dit systeem kunnen de vrijwilligers uitgenodigd worden om te helpen.
De vrijwilligers ontvangen dan een email met daarin een persoonlijke link waarop ze aan kunnen geven of ze beschikbaar zijn, welk dagdeel etc.
Vervolgens kun je dan vrijwilligers koppelen aan een taak.
Hiervan wordt vervolgens een totaal planning gemaakt en tevens een planning per persoon, beide als PDF beschikbaar.
Iedere vrijwilliger wie heeft aangegeven te willen helpen ontvangt per mail de planning voor het evenement.

verzenden mail en maken planning
Voor het verzenden van de verschillende mailtjes en het maken van de PDF bestanden maak ik gebruik van een php script wat in een iframe draait.
Zodra het script voltooid is wordt de status terug gekoppeld in het iframe.

Misschien niet de meest elegante manier van doen, maar wel een wie werkt.

probleem / uitdaging
De uitdaging in bovenstaand systeem zit hem in het feit dat wanneer het script in het iframe draait je het venster geopend moet laten en niet verder kunt op die pagina.
Ondanks popups met een waarschuwing om te wachten totdat het proces voltooid is gebeurd het toch regelmatig dat mensen het venster sluiten want: "Ik heb de server toch opdracht gegeven om...". Door het sluiten / pagina verlaten wordt het proces onderbroken. De opdrachten blijven wel in de wachtrij (tabel in MySQL) staan en kan dus later opnieuw gestart worden. Ondanks handleidingen / mailtjes blijf ik vragen krijgen waarom de mail niet verzonden wordt als ze de pagina verlaten.

mogelijke oplossing
1) accepteren dat de gebruikers het niet (willen) snappen en het systeem laten zoals het is. 8)7
2) Gebruik maken van een cronjob voor het genereren van de PDF bestanden en het verzenden van Email.
3) .....

Nadeel van optie 2 vind ik dat het hier gaat om maximaal 4 evenementen / activiteiten op jaarbasis.
Per evenement zijn er 3 tot 4 momenten waarop de cronjob daadwerkelijk iets uit te voeren heeft, voor de rest wordt deze dan nutteloos uitgevoerd.
De cronjob iedere 5 minuten uitvoeren is dan ook totaal overkill, eerder zou ik dan kiezen voor iedere 30 minuten.

Ik blijf het echter grof geschut vinden voor dit minimale aantal taken wat de cronjob uit te voeren krijgt.

Optie 3 is nog leeg, ik heb zo geen andere oplossing hiervoor.
Hoe zouden jullie dit aanpakken om te zorgen dat het systeem nog meer dummy proof wordt.
Zijn er alternatieven voor cronjob om toch te zorgen dat de taak uitgevoerd wordt ongeacht of de pagina verlaten wordt of niet?
Ik ben ze niet tegen gekomen / of heb er overheen gelezen.

alle tips en suggesties zijn welkom.

Alle reacties


Acties:
  • +2 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

skate master schreef op dinsdag 23 februari 2016 @ 12:04:
De cronjob iedere 5 minuten uitvoeren is dan ook totaal overkill, eerder zou ik dan kiezen voor iedere 30 minuten.

Ik blijf het echter grof geschut vinden voor dit minimale aantal taken wat de cronjob uit te voeren krijgt.
Denk je dat de server moe wordt of zo? Ik zou me daar geen zorgen om maken en gewoon die cron job instellen. En dan inderdaad per half of zelfs heel uur.

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • Rannasha
  • Registratie: Januari 2002
  • Laatst online: 11-10 20:26

Rannasha

Does not compute.

Kun je niet gewoon een grote "loading" animatie tonen terwijl het proces draait op de server. Eventueel met een melding (in een groot lettertype) de pagina niet te sluiten voordat het laden voltooid is.

Als je het niet met iets als een cronjob wil uitvoeren, dan is dit een manier om je gebruikers een beetje op te voeden.

[ Voor 4% gewijzigd door Rannasha op 23-02-2016 12:09 ]

|| Vierkant voor Wiskunde ||


Acties:
  • 0 Henk 'm!

  • emnich
  • Registratie: November 2012
  • Niet online

emnich

kom je hier vaker?

Gewoon een cronjob laten draaien, de server vind dat prima en als er niets te doen is, is hij er ook zo mee klaar.

Acties:
  • +1 Henk 'm!

  • YakuzA
  • Registratie: Maart 2001
  • Niet online

YakuzA

Wat denk je nou zelluf hey :X

De makkelijkste manier is idd gewoon met een cronjob doen.

De echte manier is om de gebruiker een achtergrond proces te laten starten ipv dat binnen php af te handelen, en de gebruiker niet te laten wachten op iets wat niet relevant is voor hem.

Death smiles at us all, all a man can do is smile back.
PSN


Acties:
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
YakuzA schreef op dinsdag 23 februari 2016 @ 12:28:
De echte manier is om de gebruiker een achtergrond proces te laten starten ipv dat binnen php af te handelen, en de gebruiker niet te laten wachten op iets wat niet relevant is voor hem.
Idd.

Ik vind de houding om een gebruiker maar op te zadelen met door jou opgelegde technische limitaties sowieso nogal een rare. Zorg gewoon dat je een procesje hebt draaien die dat regelt of als dat je niet lukt een PHP script vanuit een cron-job die elke X minuten checkt of er nog werk te doen is.

[ Voor 34% gewijzigd door Hydra op 23-02-2016 12:44 ]

https://niels.nu


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Er zijn helemaal geen limitaties. Het is gewoon een feit dat jij bepaalde kennis nog niet in huis hebt. Dus bij deze:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html><head>
<script>
    function updateProgressbar(percentage) {
        // doe je ding
    }
</script></head><body>
 Doe je ding hier, oftewel toon een progressbar
<?php
    ignore_user_abort(); // gebruiker sluit venster maar script blijft draaien
    set_time_limit(0); // zorgt er voor dat PHP het script niet stopt na 30 seconden
    ob_implicit_flush();
    if (ob_get_level()) {
        ob_end_clean();
    }
    // doe je ding, hieronder volgt een voorbeeld
    for ($i = 1; $i <= 100; ++$i) {
        sleep(1);
        echo '<script>updateProgressbar(', $i, ')</script>';
    }
?>
</body></html>

[ Voor 10% gewijzigd door DJMaze op 23-02-2016 13:50 ]

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 21:27
DJMaze schreef op dinsdag 23 februari 2016 @ 13:09:
Er zijn helemaal geen limitaties. Het is gewoon een feit dat jij bepaalde kennis nog niet in huis hebt. Dus bij deze:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html><head>
<script>
    function updateProgressbar(percentage) {
        // doe je ding
    }
</script></head><body>
 Doe je ding hier, oftewel toon een progressbar
<?php
    ignore_user_abort(); // gebruiker sluit venster maar script blijft draaien
    set_time_limit(0); // zorgt er voor dat PHP het script niet stopt na 30 seconden
    ob_implicit_flush();
    if (ob_get_level()) {
        ob_end_clean();
    }
    for ($i = 1; $i <= 100; ++$i) {
        // doe je ding
        sleep(1);
        echo '<script>updateProgressbar(', $i, ')</script>';
    }
?>
</body></html>
Euh... Doe je je ding dan 100 keer? Waarom niet gewoon een achtergrondproces dat geinitieerd wordt door een cronjob omdat een bepaalde flag in de database (oid) staat op "not yet processed" en alle "not yet processed" oppakt, verwerkt en daarna op "processed" zet? of gewoon een queue oid, met een subscriber die direct de boel verwerkt zodra er een message in de queue staat?

[ Voor 15% gewijzigd door Merethil op 23-02-2016 13:34 ]


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 11:48

Creepy

Tactical Espionage Splatterer

Er zijn een hoop hosters waarbij je die time_limit niet kan zetten. Maar zolang het je eigen server is kan dat wel, maar een universele oplossig is het niet.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
set_time_limit restrictie? gebruik eens:
PHP:
1
ini_set("max_execution_time", 90000000);


En er zijn ook hosters die cronjobs niet toestaan. Tja, zo ken ik er nog wel een paar.
Merethil geeft daarom gelukkig nog een ander stukje van de puzzel: processed

Er zijn heel veel wegen, maar geen limiet. Er zijn hoogstens beperkingen opgelegd die je altijd kan omzeilen.
Merethil schreef op dinsdag 23 februari 2016 @ 13:32:
Euh... Doe je je ding dan 100 keer?
Thanks, heb het voorbeeld iets aangepast.

[ Voor 20% gewijzigd door DJMaze op 23-02-2016 13:50 ]

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Ranzige bende zeg. Dat doe je toch gewoon met een back-end procesje dat bijvoorbeeld een tabel in de gaten houdt?

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Barryvdh
  • Registratie: Juni 2003
  • Laatst online: 17:41
Of met een message queue, zoals iron.io of Beanstalkd. Maar dat kan overkill zijn, dan kan je idd ook elke x minuten een cron laten checken of nieuwe taken. En andere simpele oplossing is om gewoon een proces in de achtergrond te starten, zonder te wachten op de output.

Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 11:48

Creepy

Tactical Espionage Splatterer

Toch jammer dat PHP niet zoeits als een application scope heeft (jaja, ik snap heel goed waarom dat is, maar dat maakt het in dit soort gevallen niet minder jammer)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Creepy schreef op dinsdag 23 februari 2016 @ 16:23:
Toch jammer dat PHP niet zoeits als een application scope heeft
Tja. Tijd dus om een willekeurig andere tool te gebruiken en daar gewoon een achtergrondprocesje mee te maken :)

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 21:27
Hydra schreef op dinsdag 23 februari 2016 @ 15:38:
Ranzige bende zeg. Dat doe je toch gewoon met een back-end procesje dat bijvoorbeeld een tabel in de gaten houdt?
Dat of dus een message queue oid. Een queue hoeft trouwens niet eens zo overkill te zijn, maar is wel voorbereid op de toekomst, net zoals bijvoorbeeld een back-end proces dat inderdaad een tabel in de gaten houdt. Zonde van het gedoe met je users op de frontend vervelen, het heeft geen nut en lijkt naar mijn gevoel erg onprofessioneel als zij moeten wachten omdat het programma "niet snel genoeg" is.

Acties:
  • 0 Henk 'm!

  • skate master
  • Registratie: September 2004
  • Laatst online: 12:02

skate master

Autodesk Educator Expert

Topicstarter
CyBeR schreef op dinsdag 23 februari 2016 @ 12:06:
[...]
Denk je dat de server moe wordt of zo? Ik zou me daar geen zorgen om maken en gewoon die cron job instellen. En dan inderdaad per half of zelfs heel uur.
Ik ben niet zozeer bang dat de server moe wordt. De vraag was meer bedoeld om te horen of er ook een andere oplossing was zodat niet de gebruikers de dupe worden van de verwerking van mail / pdf. Mogelijk was mijn vraagstelling hierin iets te vaag.
Hydra schreef op dinsdag 23 februari 2016 @ 12:43:
[...]
Ik vind de houding om een gebruiker maar op te zadelen met door jou opgelegde technische limitaties sowieso nogal een rare. Zorg gewoon dat je een procesje hebt draaien die dat regelt of als dat je niet lukt een PHP script vanuit een cron-job die elke X minuten checkt of er nog werk te doen is.
De keuze lijkt voor jou misschien vreemd / raar, destijds bij het ontwikkelen van de eerste versies van dit systeem was dit voor ons op dat moment de enige manier om het gewenste resultaat (verzenden / genereren PDF) te behalen. De website van de vereniging draaide op dat moment bij een van de bestuursleden welke een eigen hosting bedrijfje had. Echter was dit dusdanig uitgekleed dat o.a. cronjobs niet mogelijk waren. Nu zullen er mensen direct roepen "dan ga je daar toch weg!". Maar dat is makkelijker gezegd dan gedaan wanneer het een vereniging betreft welke draait op vrijwilligers en sponsoring (zo ook de hosting) en vooral dubbele petten (sponsor / bestuurslid).

Ik ben het eens met de mening dat het niet handig is om een gebruiker te laten wachten op bepaalde processen. Echter soms ben je hiertoe gedwongen door de omstandigheden (hosting / kennis). Om het dan direct een houding te noemen vind ik erg kort door de bocht.

Inmiddels zitten we met de website bij een andere hosting partij en kunnen we dus ook gebruik maken van de Cronjob functie.
Merethil schreef op dinsdag 23 februari 2016 @ 17:15:
[...]Dat of dus een message queue oid. Een queue hoeft trouwens niet eens zo overkill te zijn, maar is wel voorbereid op de toekomst, net zoals bijvoorbeeld een back-end proces dat inderdaad een tabel in de gaten houdt. Zonde van het gedoe met je users op de frontend vervelen, het heeft geen nut en lijkt naar mijn gevoel erg onprofessioneel als zij moeten wachten omdat het programma "niet snel genoeg" is.
Binnenkort maar eens beginnen met het opzetten van de cronjob. De queue is er al, dus heel veel werk zal het niet meer zijn.

Allen bedankt voor de aandacht en input.

Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 21:27
skate master schreef op woensdag 24 februari 2016 @ 10:36:
[...]
Binnenkort maar eens beginnen met het opzetten van de cronjob. De queue is er al, dus heel veel werk zal het niet meer zijn.

Allen bedankt voor de aandacht en input.
Voor veel queues heb je subscribers die event driven elk inkomend bericht in de queue kunnen afhandelen. Heb je geen cronjob meer nodig voor het constant pollen van die queue. Wat voor queue gebruiken jullie op die server?

Acties:
  • 0 Henk 'm!

  • skate master
  • Registratie: September 2004
  • Laatst online: 12:02

skate master

Autodesk Educator Expert

Topicstarter
Merethil schreef op woensdag 24 februari 2016 @ 10:37:
[...]


Voor veel queues heb je subscribers die event driven elk inkomend bericht in de queue kunnen afhandelen. Heb je geen cronjob meer nodig voor het constant pollen van die queue. Wat voor queue gebruiken jullie op die server?
Op dit moment is dat heel simpel een tabel in de DB met hierin de velden:
id | eventid | userid | mailtype | status

Bij het toevoegen is de status 0 en dus gereed voor verzending.
Status 1 betekent verzenden mislukt, volgende ronde nogmaals proberen.
Mislukt dit nogmaals, status naar 2.
Alle statussen van 2 en hoger worden niet automatisch opnieuw verzonden, hier moet handmatig naar gekeken worden om het eventuele probleem op te lossen en de opdracht opnieuw aan te bieden.

Geen heel geavanceerd queue systeem volgens mij, maar wel een welke in essentie voor ons zal volstaan / tot nu toe heeft gewerkt (wel op een manier welke niet de voorkeur heeft.)

Event driven subscribers klinkt interessant, ik ga hier eens in duiken.
Nog tips / valkuilen hierover te melden?

Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 21:27
skate master schreef op woensdag 24 februari 2016 @ 11:27:
[...]

Op dit moment is dat heel simpel een tabel in de DB met hierin de velden:
id | eventid | userid | mailtype | status

Bij het toevoegen is de status 0 en dus gereed voor verzending.
Status 1 betekent verzenden mislukt, volgende ronde nogmaals proberen.
Mislukt dit nogmaals, status naar 2.
Alle statussen van 2 en hoger worden niet automatisch opnieuw verzonden, hier moet handmatig naar gekeken worden om het eventuele probleem op te lossen en de opdracht opnieuw aan te bieden.

Geen heel geavanceerd queue systeem volgens mij, maar wel een welke in essentie voor ons zal volstaan / tot nu toe heeft gewerkt (wel op een manier welke niet de voorkeur heeft.)

Event driven subscribers klinkt interessant, ik ga hier eens in duiken.
Nog tips / valkuilen hierover te melden?
Welke status is een status done? Ik zou zelf je codes in een stamtabelletje vastleggen met enigszins logische waardes, zoals een 0 "ready", 1 "done", 2 "failed", 3 "re-try failed" oid. Vooral die laatste is dan belangrijk, je zou bijvoorbeeld foutcodes kunnen opnemen die staan voor "failed to send email" of "failed to create pdf" etc, dan weet je ook direct enigszins waar het probleem ligt.

Acties:
  • 0 Henk 'm!

  • skate master
  • Registratie: September 2004
  • Laatst online: 12:02

skate master

Autodesk Educator Expert

Topicstarter
Merethil schreef op woensdag 24 februari 2016 @ 11:31:
[...]


Welke status is een status done? Ik zou zelf je codes in een stamtabelletje vastleggen met enigszins logische waardes, zoals een 0 "ready", 1 "done", 2 "failed", 3 "re-try failed" oid. Vooral die laatste is dan belangrijk, je zou bijvoorbeeld foutcodes kunnen opnemen die staan voor "failed to send email" of "failed to create pdf" etc, dan weet je ook direct enigszins waar het probleem ligt.
Vergeten te melden, bij done verdwijnt de regel uit de tabel.
Hieronder een opsomming van de foutcodes met betekenis.
Mochten er fouten zijn dan kan de persoon wie de mail verzonden heeft een overzicht met foutmeldingen per vrijwilliger weergeven en dan benodigde actie ondernemen om de fout op te lossen.

0 = In wachtrij, nog niet uitgevoerd
1 = Eerste poging voor verzenden mislukt, wacht op nieuwe poging.
2 = Tweede poging voor verzenden mislukt, handmatig opnieuw aanbieden.
3 = Toevoegen bijlage mislukt, bijlage niet gevonden!.
4 = PDF aanmaken mislukt, directory is niet beschrijfbaar.

Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 21:27
skate master schreef op woensdag 24 februari 2016 @ 12:27:
[...]

Vergeten te melden, bij done verdwijnt de regel uit de tabel.
Hieronder een opsomming van de foutcodes met betekenis.
Mochten er fouten zijn dan kan de persoon wie de mail verzonden heeft een overzicht met foutmeldingen per vrijwilliger weergeven en dan benodigde actie ondernemen om de fout op te lossen.

0 = In wachtrij, nog niet uitgevoerd
1 = Eerste poging voor verzenden mislukt, wacht op nieuwe poging.
2 = Tweede poging voor verzenden mislukt, handmatig opnieuw aanbieden.
3 = Toevoegen bijlage mislukt, bijlage niet gevonden!.
4 = PDF aanmaken mislukt, directory is niet beschrijfbaar.
Weet je zeker dat je ze wilt verwijderen? Ik zou ze er zelf in laten gewoon om te laten zien dat X% van de Y zijn verwerkt, en Z% van de Y een fout hebben.
Transactie-log, zeg maar. Maar goed, als je het als queue gebruikt zou ik ze ook niet laten staan met een status, maar zou ik ze naar een "error-queue" (deadletter queue) gooien, daar gaan dan alle "dode" berichten heen. (Natuurlijk wel met hun eigen error-code voor later nog eens nakijken)

[ Voor 3% gewijzigd door Merethil op 24-02-2016 12:34 ]


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 09-10 15:13

TheNephilim

Wtfuzzle

Hydra schreef op dinsdag 23 februari 2016 @ 15:38:
Dat doe je toch gewoon met een back-end procesje dat bijvoorbeeld een tabel in de gaten houdt?
Dit! Gewoon een tabelletje vullen met informatie en een cronjob instellen die elke minuut (of 5) één of meerdere regels uit de tabel afwerkt. Hoe vaak je die cronjob laat draaien en hoeveel je er per keer afwerkt ligt aan de tijd die er per regel nodig is. Misschien is de cronjob op elke minuut instellen en dan één regel afwerken geen slecht begin.

Zorg dat de regel pas verwijderd (of afgevinkt) wordt als je script echt helemaal klaar is, maar let ook op dat je niet door een foutje bergen foutieve mail gaat versturen.

Een wat meer elegante oplossing een message queue, maar in jou situatie volstaat bovenstaande prima denk ik.

Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
skate master schreef op woensdag 24 februari 2016 @ 11:27:
Nog tips / valkuilen hierover te melden?
Stel de cronjob niet in met het commando
code:
1
wget http://example.com/cron.php

Dat is een fout die mensen maken.

Gebruik iets in de trand van:
code:
1
php-cli /home/PAD/cron.php >/dev/null 2>&1

of
code:
1
php -q /home/PAD/cron.php >/dev/null 2>&1

Maak je niet druk, dat doet de compressor maar

Pagina: 1