[PHP/MySQL] Status weergeven bij lange verwerking

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
Beste mensen,

Ik heb een script geschreven waar de cache bijgewerkt wordt in de kalender.
Ik maak gebruik van class progressbar.

Het moet ruim 6000 dagen verwerken tot een korte samenvatting, om de algemeen overzicht van kalender te kunnen weergeven zonder teveel belasting in mysql gedeelte.
Echter, de verwerking duurt langer dan ik dacht. De pagina staat al meer dan 30 seconden zonder dat er final message in zicht komt en afgesloten wordt met </HTML>

Gelukkig op de webserver van hoster is timeout waarde hoog genoeg zodat de hele proces niet onderbroken wordt.
Toch neemt de risico wel meer toe dat de proces toch nog gestopt wordt als er nog meer dagen bijkomen. Hoe meer dagen, hoe langer verwerking, en komt dichtbij de time-out grens.
Om de risico van stopzetting klein te houden wil ik proberen pagina te verversen of progress bar verbeteren (b.v. Javascript of zo) zodat time-out risico klein blijft. In feite dus server beetje poken om zaak wakker te houden.

Ik ken maar weinig zaken hoe ik progress kan weergeven en dat php script door blijft draaien.
De methode van classprogressbar (die in feite eigenlijk stukje voor stukje image achter elkaar plakt in de pagina en zoveel mogelijk geflusht wordt (ivm html buffer) zodat progress alsnog te volgen is.
In praktijk blijkt dat niet goed te werken. Er zit geen zichtbaar progress in! De bar groeit niet. Ondanks dat buffer wel vol wordt en moet kunnen flushen....

Ik vraag dus aan jullie of jullie al een mogelijk oplossing hebt op mijn probleem situatie? De scripttaal is PHP en gegevens worden in MySQL opgeslagen. Er mag gebruik gemaakt worden van java/javascript. De Perl taal ken ik. Daar heb ik demo's van gezien. Maar mijn server kan perl voor zover ik weet nog niet aan. CGI weet ik niet. De keuze zal dus naar java(script) gaan.

Ik ben erg benieuwd naar en het is belangrijk, het is voor de website van mijn klant. _/-\o_

Acties:
  • 0 Henk 'm!

  • flashin
  • Registratie: Augustus 2002
  • Laatst online: 17-12-2023
Ik heb een script geschreven waar de cache bijgewerkt wordt in de kalender.
Ok je cached het dus
Het moet ruim 6000 dagen verwerken tot een korte samenvatting, om de algemeen overzicht van kalender te kunnen weergeven zonder teveel belasting in mysql gedeelte.
Echter, de verwerking duurt langer dan ik dacht. De pagina staat al meer dan 30 seconden zonder dat er final message in zicht komt en afgesloten wordt met </HTML>
Hoezo is dit veelste belastend voor mysql? is toch maar 1 querytje per maand.
Daarnaast hoef je die cache echt niet bij iedere hit te updaten, dus ik begrijp het probleem niet helemaal.

Volgens mij valt er meer te optimaliseren in je code dan door zo'n progressbar te gebruiken. Het is leuk maar mensen willen toch echt zo snel mogelijk results hebben.

Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
PEAR::Progress gebruiken, maar die gebruikt ook weer javascript.

Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
Ja, er zijn 20 caravans. Ik moet voor 4 algemene cijfers op kalender bezettingswaarde uitrekenen van alle caravans, en dat ook nog 365 dagen lang. 20x365 is dus veel velden voor 1 jaars kalenders.
Er zit meerdere routines in voor correct uitrekenen en verzamelen dagen.

Zie voorbeeld op www.vdsluisvakanties.nl in Bezetting pagina.

Als ik deze 4 algemene waarden voor overall, ameland, terschelling en bakkeveen niet van te voren doet en dus gewoon 'ter plekke' laat uitrekenen, dan is vertraging gewoon te groot, en als meerdere mensen ook nog op website klikt, dan wordt server veel te veel belast.

Door algemene waarden reeds van te voren uit te rekenen en ze opslaan in mysql, hoeven ze niet meer nog een keer uigerekend worden en kan dus direct gelezen worden voor publiek. Dit hoeft maar 1 keer gebeuren en is klaar. Dat heet dus cache voor algemene cijfers.

Hiervoor wil ik progressbar laten zien aan de klant hoe het gaat.
Heb intussen paar scripts gevonden, ga ze even uittesten of ze goed werken.
Het moet real-time bar tonen terwijl php mee bezig is. Vooral zonder pagina te reloaden.

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 23:12
Ik zou hier een soort van multithreading inzetten. Je maakt een PHP (cli) script dat het cachen voor je verzorgt. Deze laat je status informatie uitpoepen in een textbestand. Je progress-pagina hoeft dan alleen maar het status bestand uit te lezen. Bijkomend voordeel is dat je kunt voorkomen dat de operatie meerdere keren simultaan wordt uitgevoerd. Zolang er *running* in je statusbestand staat laat je het script niet nogeens opstarten.

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
T-MOB schreef op zondag 04 december 2005 @ 13:04:
Ik zou hier een soort van multithreading inzetten. Je maakt een PHP (cli) script dat het cachen voor je verzorgt. Deze laat je status informatie uitpoepen in een textbestand. Je progress-pagina hoeft dan alleen maar het status bestand uit te lezen. Bijkomend voordeel is dat je kunt voorkomen dat de operatie meerdere keren simultaan wordt uitgevoerd. Zolang er *running* in je statusbestand staat laat je het script niet nogeens opstarten.
Dat dacht ik ook aan als andere optie. Het plaatst piepklein txt filetje met status op server, die door javascript of flash (die zelfstandig kan lopen los van cache verwerking routines) ingelezen wordt en status toont.

Ik probeer eerst dynamische scripts die nu beschikbaar zijn, dan probeer ik die losse txt file inlezing via andere pagina (b.v. in popup venster, zonder pagina zelf te poken, anders stopt de script)

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 23:12
MrDummy schreef op zondag 04 december 2005 @ 13:11:
[...]
Ik probeer eerst dynamische scripts die nu beschikbaar zijn, dan probeer ik die losse txt file inlezing via andere pagina (b.v. in popup venster, zonder pagina zelf te poken, anders stopt de script)
Dat bedoel ik niet helemaal. Ik bedoel dat je de routine zelf een serverprocess maakt wat je op de achtergrond start zodra de klant een pagina aanroept. Eenmaal gestart schrijft de achtergrondroutine statusinfo naar een bestandje dat je op de "voorgrond" kunt lezen.
Je voorkomt dat een klant het process half runt, twee maal tegelijk runt en dat soort spul. De klant kan het proces starten, voor mijn part zijn computer rebooten, terugkomen en kijken hoever het er mee staat.

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Not Pingu
  • Registratie: November 2001
  • Laatst online: 05-08 09:21

Not Pingu

Dumbass ex machina

MrDummy schreef op zondag 04 december 2005 @ 12:39:
Door algemene waarden reeds van te voren uit te rekenen en ze opslaan in mysql, hoeven ze niet meer nog een keer uigerekend worden en kan dus direct gelezen worden voor publiek. Dit hoeft maar 1 keer gebeuren en is klaar. Dat heet dus cache voor algemene cijfers.

Hiervoor wil ik progressbar laten zien aan de klant hoe het gaat.
Heb intussen paar scripts gevonden, ga ze even uittesten of ze goed werken.
Het moet real-time bar tonen terwijl php mee bezig is. Vooral zonder pagina te reloaden.
Afhankelijk van hoe de data wordt aangepast, zou je natuurlijk in de backend de berekeningen plaats kunnen laten vinden, zodra de beheerder op Opslaan klikt (even metaforisch gesproken dus).

Ik weet niet hoevaak de data geupdate zal worden, maar stel dat er per 1000 selects van de data, 1 update/insert zal plaatsvinden, dan ga je dus moeilijk lopen doen voor iets dat eens per 1000 pageviews voorkomt.
Zorg gewoon dat een bezoeker altijd data vanuit de cache krijgt, en doe het updaten van de cache in de backend of in het automatische proces dat de data update.

Certified smart block developer op de agile darkchain stack. PM voor info.


Acties:
  • 0 Henk 'm!

  • StevenK
  • Registratie: Februari 2001
  • Laatst online: 06:30
MrDummy schreef op zondag 04 december 2005 @ 11:47:
Beste mensen,

Ik heb een script geschreven waar de cache bijgewerkt wordt in de kalender.
Ik maak gebruik van class progressbar.

Het moet ruim 6000 dagen verwerken tot een korte samenvatting, om de algemeen overzicht van kalender te kunnen weergeven zonder teveel belasting in mysql gedeelte.
Echter, de verwerking duurt langer dan ik dacht. De pagina staat al meer dan 30 seconden zonder dat er final message in zicht komt en afgesloten wordt met </HTML>
Klinkt alsof je je SQL code en/of de inrichting van je indices moet optimaliseren.

Was advocaat maar vindt het juridische nog steeds leuk


Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
StevenK schreef op zondag 04 december 2005 @ 13:32:
[...]

Klinkt alsof je je SQL code en/of de inrichting van je indices moet optimaliseren.
Ik beschrijf ff de procedures voor die ik heb gedaan in mijn script.

> fase1: cache leegmaken
Alle dagen weghalen voor nieuwe cache data uit MySQL

> fase2: (dit is meeste optelwerk)
1. Er wordt boekinfo-array gemaakt alle dagen die geboekt zijn (ja uit MySQL overhevelen naar server). De locatie id's worden ook opgeslagen in de boekinfo-array,
2. Per locatie wordt nu gezocht naar de dagen die bij locatie id horen in boekinfo-array.
Gevonden: dagteller (voor resultaat-array) verhogen. Daarna wordt gevonden record in boekinfo-array nul gemaakt zodat het niet dubbel geteld wordt (telfouten voorkomen).
Als array is doorlopen, wordt er gemiddelde bezettingswaarde bepaald + dagteller + timestamp in resultaat array gezet.
Daarna gaat het verder naar volgende record uit boekinfo-array, zoekt weer alle dagen op die erbij horen, gevonden, nul-maken, opslaan in resultaat array, volgende record, gevonden-nul maken, zoeken, opslaan, volgende, zoeken.... totdat het bij laatste record komt. De lege records staan wel erin, maar worden overgeslagen.
Dat gebeurt drie keer voor 3 locaties. 3x count(array) x count(array) in boekinfo-array doorlopen.

> fase3:
Resultaat array (opgetelde dagen dus) worden nu in MySQL opgeslagen

>fase4:
Nu worden alle dezelfde dagen in Resultaat array opgeteld per dag. Dat komt in nieuwe Allresult-array te staan. Je hebt dan algemeen beeld van alle 3 locaties.
De allresult array wordt nu in MySQL opgeslagen

Cache datum bijgesteld zodat men kan zien dat het overeenkomt met boekinfo database. Klaar.

Je kan wel zien dat fase 2 grote klusje is. Misschien moet ik eigenlijk alle arrays unsetten die niet nodig zijn, maar dan moet de count(array) weer bijgesteld worden. Door nul te maken blijft record staan, maar wordt wel overgeslagen. De boekinfo-array is nog steeds groot met aantal nullen die gecontroleerd zijn. Voordeel is wel dat count waarde niet opnieuw ververst hoeft te worden en kan dus 3maal in de lus blijven lopen.
In pricipe moet ik andere array commando's gebruiken zoals next() en reset() en zo voor meer effectief doorlopen. Unsetten maakt array steeds kleiner en is hele klus sneller klaar bij volgende locaties.

Fase 2 maakt licht gebruik van mysql_query voor locatieid's omdat meeste al in array is opgeslagen.
Process bar wordt weergegeven in Fase 2.

Nu mag je je reactie op geven.

Acties:
  • 0 Henk 'm!

  • StevenK
  • Registratie: Februari 2001
  • Laatst online: 06:30
Die fase 2, kun je die niet beter in SQL uitvoeren, want nu ben je aan het zoeken in een niet-geïndexeerd array.

Was advocaat maar vindt het juridische nog steeds leuk


Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
StevenK schreef op zondag 04 december 2005 @ 17:31:
Die fase 2, kun je die niet beter in SQL uitvoeren, want nu ben je aan het zoeken in een niet-geïndexeerd array.
Ik wil de risico van dubbel tellen klein houden, maar ik zal even zaak herzien en nadenken.
Ik weet dat je resultaat van sql query kunt krijgen in mysql_num_rows() wat dus beetje overeenkomt met dagteller als de zoekstring in WHERE goed geformuleerd is.

Vraag me alleen af of server wel leuk vindt met 3x bijna alle dagen van kalender nalopen met maximaal 365 mysql queries... 8)7

Acties:
  • 0 Henk 'm!

  • StevenK
  • Registratie: Februari 2001
  • Laatst online: 06:30
MrDummy schreef op zondag 04 december 2005 @ 18:17:
[...]

Ik wil de risico van dubbel tellen klein houden, maar ik zal even zaak herzien en nadenken.
Ik weet dat je resultaat van sql query kunt krijgen in mysql_num_rows() wat dus beetje overeenkomt met dagteller als de zoekstring in WHERE goed geformuleerd is.

Vraag me alleen af of server wel leuk vindt met 3x bijna alle dagen van kalender nalopen met maximaal 365 mysql queries... 8)7
Dan had 'ie maar geen databaseserver moeten worden. Juist door tabellen op de juiste manier de indexeren zorg je er voor dat dit soort acties op een databaseserver heel snel gaat.

Was advocaat maar vindt het juridische nog steeds leuk


Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Topicstarter
StevenK schreef op zondag 04 december 2005 @ 18:28:
[...]

Dan had 'ie maar geen databaseserver moeten worden. Juist door tabellen op de juiste manier de indexeren zorg je er voor dat dit soort acties op een databaseserver heel snel gaat.
Ik heb nu mysql methode gebruikt. Ik zoek nu alles op vanaf mysql en gebruik resultaat uit mysql_num_rows().
Totaal 4x 365 dagen, elke keer mysql_query gedaan

Verschil is heel groot. Het is sneller klaar dan ik dacht!

De progress bar is alleen nog wel fout weergegeven... dus ga even andere scripts bekijken voor progress bar.
---------------
Edit:

Heb verbeterde progressbar gevonden en codes goedgezet. Nu werkt het uitstekend naar mijn wens; de voortgang is zichtbaar te volgen.

En bedankt voor advies om mysql te gebruiken. Het is klaar binnen 30 seconden.
De nieuwe cache routines zijn nu:
> fase 1: cache leegmaken

> fase 2: zoekstrings maken voor mysql_query

> fase 3: zoeken per locatie (met zoekstring) per dag, opslaan in resultaat array (dat gebeurt dus 3 keer 365 dagen)

> fase 4: opslaan resultaat in cache

> fase 5: bezettingsgraad van elke dag opzoeken uit mysql (alle locaties samen) en resultaat opslaan in cache

-------------
Edit 2:
Maar de test toont aan dat nieuwe methode met mysql toch niet helemaal goed is. Misschien is er een controle te scherp toegepast. Dat wordt debuggen :( Ben al moe van proggen, doe ik morgen wel.
Gebruik nu nog even oude script (maar wel werkende progressbar) omdat deze uitstekend alles optelt en dus naar wens werkt.

[ Voor 49% gewijzigd door MrDummy op 04-12-2005 22:14 ]

Pagina: 1