Kun esim. huuto.net:issä tuotteen huuto päättyy, niin siellä suoritetaan jokin scripti, joka lähettää huutokaupan osapuolille sähköpostia.
Ongelmani:
Minulla on tietokantataulu, jonka riveissä on date-tyyppinen sarake. Kun date-muotoisesta ajan hetkestä on kulunut viikko, pitäisi suorittaa scripti, joka tekee tietokantakyselyn (updatea kyseiselle riville) ja kenties muuta kuten sähköpostin lähettäminen. En halua tutkia taulun rivejä jatkuvasti php:llä koska se kuormittaa palvelinta ja edellyttää jonkun avaavan tietyn php-sivun.
Millä tekniikalla/ohjelmointikielellä onnistuisi tehdä tuo ajastettu palvelimella suoritettava scripti, jonka ajastus tapahtuisi samalla kun tietokannan rivi luodaan?
Tietääkseni yleensä tehdään ajastetulla ohjelmalla, joka tarkistaa kyseisen date-kohdan tietokannasta ja tekee tarvittavat toimenpiteet. Itse ajastamiseen Cron on suosittu, ja tulee monissa web-hostaus palveluissa mukana.
Tuon voi toteuttaa ihan käyttöjärjestelmän normaaleilla ajastustoiminnoilla (esim. cron). Minusta on kuitenkin käytännöllisempää vain ajaa säännöllisesti asianmukainen tietokantahaku ajastamalla sivunlataus vaikka minuutin välein. Kolmas mahdollisuus on pyörittää erillistä prosessia, jolle PHP ilmoittaa muutoksista ja joka nukkuu aina seuraavaan tunnettuun ajohetkeen asti. Jos optimointi kiinnostaa, tuolle prosessille voi vaikka vihjata aina muutoksista, jolloin se voi ajastaa itsensä nukkumaan seuraavaan ajoon asti.
Kiitti vastauksista.
Miten tästä eteenpän:
Tutustun croniin ja siihen voinko käyttää cronia palvelinpalveluntarjoajallani.
Suunnittelin että tekisin eri aikavälein suoritettavia php-filuja ja säädän ne ajettavaksi cronilla. Filuja olisivat esim. minuutti.php, minuutti10.php, tunti.php, vuorokausi.php, viikko.php ja kk.php.
Noihin filuihin kokoan sitten haluamiani funktioita kätevästi aina kun tarvitsen jotain ajastustehtävää. Esim. minuutti.php:n laitan tuon taulun tarkistuksen, jossa tutkitaan onko date-sarakkeista kulunut se viikko ja jos on niin tehdään tarvittavat muutokset kys. riville. Heittoahan tuossa voi tulla se max.59sekuntia siitä hetkestä kun viikko on oikeasti kulunut, mutta en usko sen haittaavan.
Näillä mennään. :)
villapaita kirjoitti:
Heittoahan tuossa voi tulla se max. 59 sekuntia siitä hetkestä kun viikko on oikeasti kulunut, mutta en usko sen haittaavan.
Käyttäjän päässä heittoa tulee yleensä selvästi enemmän, ja postikaan ei aina kulje sekunnissa. Kannattaa kuitenkin harkita ajan pyöristämistä tasaminuutteihin tai vaikka seuraavaan kymmeneen minuuttiin, tämä selkeyttää sivuston ilmettä.
Sen verran vielä, että tauluun kannattaa varmuuden vuoksi lisätä sarake, josta selviää, onko rivi jo käsitelty. Näin viestejä ei jää välistä, vaikka palvelimella olisi käyttökatko eikä skriptiä ajettaisikaan joka minuutti.
SELECT * FROM taulu WHERE aika <= NOW() AND kasittelyaika = NULL -- ... UPDATE taulu SET kasittelyaika = NOW() WHERE id = (nyt käsiteltävä)
Tuossa viimeksi mainitussa tapauksessa täytyy sitten olla todella tarkkana ettei skripti pääse pyörähtämään uudelleen ennenkuin edellinen on suoritettu loppuun. Näin voi käydä esimerkiksi jos rivejä tulee niin paljon, että käsittelyyn menee yli minuutti. Muuten viestit voi lähteä kahteen kertaan.
Metabolix kirjoitti:
Kannattaa kuitenkin harkita ajan pyöristämistä tasaminuutteihin tai vaikka seuraavaan kymmeneen minuuttiin, tämä selkeyttää sivuston ilmettä.
Joo, kymmenminuutit voisi olla hyvä. Sopivan harvoin (palvelimen kuormitus), mutta riittävän usein (tapahtumalle luvattu viikko on silti viikko riittävällä tarkkuudella).
Metabolix kirjoitti:
Sen verran vielä, että tauluun kannattaa varmuuden vuoksi lisätä sarake, josta selviää, onko rivi jo käsitelty.
Sarakkeissa on jo enum-tyyppinen tilamuuttuja, jonka tietty tila vaaditaan, jotta se viikon jälkeinen kysely suoritetaan. Kysely muuttaa tilamuuttujaa, joten muuttujan tilasta selviää onko rivi käsitelty.
Grez kirjoitti:
Muuten viestit voi lähteä kahteen kertaan.
-Scriptini suunnittelin toimivan näin:
1.Hae päivitystarpeessa olevat rivit.
2. Päivitä ne ja lähetä sähköposti jos tarpeen.
Tuo kahteen kertaan voisi tapahtua jos rivin updatettaminen olisi paljon hitaampaa kuin selectointi, jolloin jälkimmäinen tarkastuskerta saisi ensimmäisen "tarkastajan" kiinni käsiteltävissä riveissä, koska ensimmäisellä on kulunut aikaa updatettamiseen samalla kun jälkimmäinen on ohittanut selecteillä juuri updatetetut rivit nopeasti.
Lisäksi updatetettavia rivejä pitäisi olla tuhoton määrä. Ei toteudu sivullani, mutta jatkan vielä worst case scenarion analysointia:
Tuon voisi välttää niin että teen sql-kyselyn ja sähköpostin lähettämisen transaktiotapahtuman sisällä, jolloin taulun rivi on varattuna transaktiotapahtuman ajan. Näinollen seuraava "tarkastaja" ei pääse edes lukemaan riviä ennen kuin se on vapautettu edellisestä transaktiotapahtumasta. Seuraava "tarkastaja" ei käsittääkseni kumminkaan kaatuisi vaan odottaisi kiltisti jonossa rivin käyttöoikeuden vapautumista. Sitten kun seuraava "tarkastaja" pääsee saman rivin kimppuun, on sen tilamuuttuja jo muutettu sellaiseksi ettei riviä lähdetä muuttamaan eikä mailia lähettämään.
No transaktiot on tietenkin yksi hyvä tapa huolehtia siitä, ettei kaksi erillistä säiettä/prosessia käsittele samaa tietoa. Lähinnä nyt mainitsin asian, koska tyypillisissä php/mysql virityksissä transaktioiden käyttö on enemmän poikkeus kuin sääntö.
Aihe on jo aika vanha, joten et voi enää vastata siihen.