• 30 odgovora
  • 9.554 pregleda
Izvršavanje funkcije u pozadini 05.10.2010. u 11:40 · pre 195 meseci #1
Potrebno je da napravim funkciju koja će da se izvršava na serveru u pozadini, a da ostatak sajta normalno funkcioniše. Nešto kao niti u Javi. Gledao sam PCNTL proširenje za php, međutim za njega je potrebno ručno kompajlirati php.
Da li je nešto ovako uopšte moguće u php? Nov sam u php, pa me baš iznenadilo da se ovako jednostavna stvar tako teško rešava.

P.S. Funkcija čita podatke iz baze, radi neke proračune, i upisuje u bazu.
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 12:08 · pre 195 meseci #3
Pojasni malo vise sta ti konkretno treba?
Zasto jednostavno ne resis taj problem tako da kada god ti dodje neki korisnik na sajt da on pokrene tu funkciju koja nesto odradi?
Ukoliko ti treba da ti se funkcija odradi odredjeni broj puta u odredjeno vreme bez obzira da li neko posacuje sajt ili ne onda ti treba Google: "php cron job".
Iskreno, ja ga nikad nisam koristio i ne znam kako se koristi ali na svim novijim hosting serverima imas u njihovom cPanelu ugradjenu podrsku sa Cron, ako sam ja dobro primetio.
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 15:13 · pre 195 meseci #4
Ajax ti može pozivati PHP fajl u pozadini, a taj PHP će raditi šta treba, ali to samo radi kad je posetilac na strani koja poziva ajax.

Kao što ksrele reče, ako ti treba nešto da se obavlja u određenim vremenskim intervalima, rešenje je cron job. Imaš ovde uputstvo za cPanel.
Potpis
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 17:17 · pre 195 meseci #5
Hvala svima na ovako brzim ogdovorima.

Da malo konkretizujem problem. Pravim modul za Drupal koji će da omogu peni aukcijsku prodaju (penny auctions), nešto po uzoru na swoopo.com. Ovo pitanje je vezano za bid butlers (agente prodaje, kako ih ja zovem) koji automatski postavljaju ponude. Svaki korisnik može da aktivira neki i on će se izvršavati nezavisno od toga da li je korisnik ulogovan. Prema tome ne može preko AJAX-a da se realizuje.

Što se tiče cron-a tu je opet problem što se to neće izvršavati u jednakim vremenskim intervalima, već će morati konstantno da se izvršava. Moja ideja je da se kreira beskonačna petlja koja će spavati po 1s i onda proveravati da li ima potrebe da postavi neku ponudu. Ako ima potrebe, da odradi posao i onda opet na spavanje.

Imam osećaj kao da mi neki osnovni koncept tu izmiče, i da ne razmišljam baš na najbolji način. Dakle, rad u pozadini nije sa aspekta korisnika, već sa aspekta ostatka sajta koji treba da nastavi da funkcioniše normalno kao i da ne postoje ovi agenti prodaje.
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 17:32 · pre 195 meseci #6
Ako sam dobro razumeo sta ti treba evo ti moja vizija resenja:

1. u bazi cuvaj statuse za korisnike koji su se prijavili za automatsko "bidovanje"

2. Napravis skript koji proverava te statuse i radi sta vec treba da radi.

3. U cron tabu podesis da se taj skript izvrsava na svakih 5 sekundi


Ovo sve pije vodu ako sam dobro skontao sta hoces da postignes...

pozdrav
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 17:52 · pre 195 meseci #7
Zar nije najmanja jedinica za cron 1 minut? Ne znam kako da podesim da mi se cron izvrsava ispod toga.
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 17:55 · pre 195 meseci #8
A jel tebi treba da se skripta uvek konstantno izvrsava ili samo kada se pojavi nova ponuda? Da li mozes odmah nakon postavljanja ponude da pozoves odmah sve bid butlerse za tu ponudu i onda oni rade to sto treba da rade (biduju ili salju mail ili sta vec)? Mislim da tako limundov "agent prodaje" ili kako ga vec zovu radi, inicira se odmah nakon postavljanja nove ponude (posle svakog bida)
Potpis
http://norway.dakipro.com/
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 18:18 · pre 195 meseci #9
Skripta se izvšava samo za one proizvode kod kojih je vreme do kraja palo ispod 10s. Ona jedanput iskenira sve "agente prodaje" i proizvode vezane za njih i to smesti u jednu promenljivu kako ne bih svaki put slao upit ka bazi. Ukoliko je najmanje vreme do kraja neke aukcije recimo 5 min, onda će skripta da spava narednih 4 min 50s; sem ukoliko neko ne kreira neki novi proizvod, čime se pokreće ponovo skeniranje (postoji mogućnost da taj proizvod ima manje od 5 min do kraja) ili ukoliko neko ne kreira novog "agenta prodaje" (postoji mogućnost da taj agent bude vezan za neki proizvod koji ima manje od 5 min).
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 18:23 · pre 195 meseci #10
Ja bih ovo rešio sa dva procesa, jedan koji spava u beskonačnoj petlji, i drugi koji se izvršava sa veb stranice (pristup php skriptu) koji sa prvim razmenjuje podatke. Zavisno od opterećenja i robustnosti koju planiraš možeš da između postaviš i jedan message queue sistem, koga će veb stranica da pinguje kada se pojavi nova aukcija ili postavi novi robot, a koji će da isporuči to ovom uspavanom iz pozadine.

Ne vidim razlog da pokrećeš po jedan proces za svakog korisničkog agenta/aukciju, jedan proces je sasvim dovoljan, eventualno ako ti je lakše da tako dizajniraš sistem, jedna nit po aukciji i svakako odvojena nit za komunikaciju sa PHP skriptom na veb stranici ili sa MQ sistemom.
Potpis
http://sr.libreoffice.org — slobodan kancelarijski paket, obrada teksta, tablice,
prezentacije, legalno bez troškova licenciranja
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 18:39 · pre 195 meseci #11
To, to je pravo rešenje :). U početku sam i imao ideju da za svaku aukciju kreiram zasebnu nit, ali sam na kraju sve smestio u jednu funkciju. Međutim, kao što rekoh, nov sam u php-u i ne znam kako funkcioniše to sa nitima ovde i MQ sistemom. Konkretno, ne znam kako da probudim taj proces koji spava. Je l' imaš možde niki link gde mogu to opširnije da pogledam. Recimo, gledao sam za PCNTL proširenje za php, i to je to što meni treba, ali je potrebno ručno kompajlirati php.
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 18:58 · pre 195 meseci #13
Ja bih isao preko krona za ovo.

Treba ti neka tabela (txt fajl ili sta god) gde ces upisivati zadnju akciju koja se pozvala iz krona. Svaka akcija se upisuje i ispisuje prilikom zavrsenja posla. Akcije koje se jave u medjuvremenu kontaktiraju taj fajl i ukidaju se ukoliko ima aktivnog procesa.

Ovde treba viditi racuna o tome da se skript ne zaglupi - to znaci da treba postojati interval na koji ce upisivati status u ovu datoteku. Ukoliko nova akcija vidi da je skript aktivan dize paniku - ubija proces, obavestava mejlom, ili sta god.

Dakle, slep ali sa jednim okom otvorenim ;)
Potpis
Moj Veb Sajt HostCentar Blog
Aleksinac Južna Srbija TimeOut
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 19:29 · pre 195 meseci #14
Citat:
Goran Rakić: Ne razumem, kako to misliš da probudiš nit koja spava?

Recimo, imam
Code (php):

function neka_funkcija(){
  // radi nesto
 
  sleep(50);
}
 

Međutim, ja poželim da prekinim to spavanje i da pozovem funkciju posle 10s. Da li je to moguće?

I mnogo važnija stvar, ja ne znam kako da pokrenem recimo dve niti da mi rade paralelno. Tražio sam po netu i ništa nisam našao sem PCNTL-a. Znam da je to neka osnova, ali
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 20:31 · pre 195 meseci #15
Ja citam vec par puta poruke i ne kontam kakve procese spominjete u PHP-u :) ali nema veze...

Zar ne mozes to rijesiti nekako ovako:

Code (php):

<?php
// negdje na samom pocetku koda (recimo index.php)
if( provjeri_uslov() )
{
   akcija();
}

//....
//... nastavak index.php

?>

 


Funkcija provjeri_uslov() bi pogledala u neku optimizovanu tabelu u MySQL da li treba izvrsiti akciju ili ne.

Sto moras svaku sekundu nesto raditi, ako nema ni jednog korisnika na sajtu?! :)
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 20:44 · pre 195 meseci #16
Citat:
Faun: Recimo, gledao sam za PCNTL proširenje za php, i to je to što meni treba, ali je potrebno ručno kompajlirati php.

PCNTL je verovatno najbolje rešenje za implementaciju multithreading-a u PHP-u. Naravno, postoje i alternative. Ova tri članka ti možda mogu biti od pomoći što se PCNTL-a tiče:
http://www.re-cycledair.com/php-dark-arts-multi-threading-part-1
http://www.re-cycledair.com/php-dark-arts-multi-processing-part-2
http://www.re-cycledair.com/ph...rts-shared-memory-segments-ipc

btw Izgleda da nisam najbolje razumeo ono što ti hoćeš da postigneš, jer ne mogu da skapiram zašto bi igranje sa procesima bilo rešenje za taj tvoj problem.
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 20:45 · pre 195 meseci #17
@vatri, izgleda da nisi citao par puta dobro sve poruke ;)
Treba da se skripta pozove u recimo 11:59:50 iako tada nema nikog na sajtu, jer je to vreme dogadjaja nekog eventa na sajtu (isticanje aukcije ili sta vec)
Potpis
http://norway.dakipro.com/
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 21:32 · pre 195 meseci #18
Dobro, a u cemu je problem ako se recimo taj "event" dogodi u 12 h, tj. kad prvi korisnik poslije tog vremena dodje na sajt?

U bazi imas vrijeme izvrsavanja eventa i u provjeri_uslov() funkciji jednostavnim query-jem uporedimo NOW() i vrijeme eventa...
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 21:57 · pre 195 meseci #19
Citat:
vatri: Dobro, a u cemu je problem ako se recimo taj "event" dogodi u 12 h, tj. kad prvi korisnik poslije tog vremena dodje na sajt?

U bazi imas vrijeme izvrsavanja eventa i u provjeri_uslov() funkciji jednostavnim query-jem uporedimo NOW() i vrijeme eventa...

To bi bilo komplikovanije za implementaciju. Ima dosta AJAX-a, što znači da bih ja u svaku metodu koja se poziva preko ajax-a prvo trebalo da ubacim da mi se izvrše svi "agenti prodaje" koji su bili planirani od poslednjeg pristupanja. A druga stvar, šta ako niko ne poseti sajt danima, a ima gomila "agenata prodaje" koji čekaju (jedan "agent prodaje" može da se izvrši i više puta, verovatno će biti ograničeno na 50, ali treba ostaviti korisniku da odredi taj broj). Nisam siguran, ali meni to izgleda da bi moglo da uspori stvari.

Citat:
Nikola Poša: btw Izgleda da nisam najbolje razumeo ono što ti hoćeš da postigneš, jer ne mogu da skapiram zašto bi igranje sa procesima bilo rešenje za taj tvoj problem.

Krenuo sam sa idejom da svaki "agent prodaje" ima svoju nit koja će da postavlja ponude. Pošto sam onda video da ću verovatno imati problema sa multi-threading-om u php, onda sam sve strpao u jednu metodu tako da ručno vodim računa o rangiranju i vremenu izvršavanja svih "agenta prodaje". Tu funkciju ću pozvati preko cron-a.

Sada mi ostaje još da odradim prenošenje poruka. Tj. kako da neka druga funkcija posalje poruku ovoj prvobitnoj da je doslo do promene nekih podatak u bazi kako bi ona učitala sveže podatke.agvozden je predložio
Citat:
agvozden: Treba ti neka tabela (txt fajl ili sta god) gde ces upisivati zadnju akciju koja se pozvala iz krona. Svaka akcija se upisuje i ispisuje prilikom zavrsenja posla. Akcije koje se jave u medjuvremenu kontaktiraju taj fajl i ukidaju se ukoliko ima aktivnog procesa.
ali me zanima da li postoji još neko rešenje, bez upisa u fajl ili bazu, preko neke promenljive.
Re: Izvršavanje funkcije u pozadini 05.10.2010. u 22:54 · pre 195 meseci #20
Mislim da to što si zamislio može jednostavnije da se implementira.

Počni od problema, a ne od rešenja. Hajde definiši te agente, šta oni rade i kako se odnose prema drugim objektima.

Onaj sleep ne prekidaš (možda može nekim signal handlerom, ali to je nepotrebno). Ako hoćeš aktivno čekanje, onda imaš petlju tipa:
Code (php):
while(true) {
  // nešto
  sleep(1);
}

Sada u samoj petlji možeš da postaviš uslov tipa if(treba_li_da_se_izvrši) ..., i ako ne treba ideš ponovo na čekanje od 1sec.

Još bolje je da imaš neku blokirajuću funkciju, na primer socket_select ili zatražiš neki katanac (engl. lock), koja će ti prekinuti čekanje tek kada se dogodi neki upis na jednom od nadgledanih socketa ili kada oslobodiš katanac iz druge niti/procesa.

Međutim veoma je verovatno da u ovom tvom konkretnom slučaju sve to može jednostavnije.
Potpis
http://sr.libreoffice.org — slobodan kancelarijski paket, obrada teksta, tablice,
prezentacije, legalno bez troškova licenciranja
Odgovori
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme