resim nasledujici problem a verim, ze mi nekdo z vas pomuze.
Potrebuji z cgi skriptu (interpretuje jej jednoduchy httpserver) pustit dlouho bezici ulohu ale tak abych nemusel volat mutiprocess.join(), protoze pak stranka zustane viset. Jak jsem zminil pouzivam k tomu multiprocess, ktery pouze nastartuji ale nejoinu. Vse ale nasvercuje tomu, ze proces je zabyt i kdyz by mel byt daemonem.
proces je ukonceny pretoze jeho parent skoncil (proces web serveru -> CGI skript). Ak si na linuxe, tak toto nie je mozne takymto sposobom urobit (resp. nie je mi znamy sposob). Ine OS neviem.
> Od: "Tomas Pelka" <tompe...@gmail.com>
> Komu: <Pyt...@py.cz>
> Dátum: 05.09.2012 09:51
> Predmet: [python] multiprocess problem se sirotkem
>Zdravim vsechny,
>resim nasledujici problem a verim, ze mi nekdo z vas pomuze.
>Potrebuji z cgi skriptu (interpretuje jej jednoduchy httpserver) pustit >dlouho bezici ulohu ale tak abych nemusel volat mutiprocess.join(), >protoze pak stranka zustane viset. Jak jsem zminil pouzivam k tomu >multiprocess, ktery pouze nastartuji ale nejoinu. Vse ale nasvercuje >tomu, ze proces je zabyt i kdyz by mel byt daemonem.
> proces je ukonceny pretoze jeho parent skoncil (proces web serveru -> CGI skript). Ak si na linuxe, tak toto nie je mozne takymto sposobom urobit (resp. nie je mi znamy sposob). Ine OS neviem.
> azur
> ______________________________________________________________
>> Od: "Tomas Pelka"<tompe...@gmail.com>
>> Komu:<Pyt...@py.cz>
>> Dátum: 05.09.2012 09:51
>> Predmet: [python] multiprocess problem se sirotkem
>> Zdravim vsechny,
>> resim nasledujici problem a verim, ze mi nekdo z vas pomuze.
>> Potrebuji z cgi skriptu (interpretuje jej jednoduchy httpserver) pustit
>> dlouho bezici ulohu ale tak abych nemusel volat mutiprocess.join(),
>> protoze pak stranka zustane viset. Jak jsem zminil pouzivam k tomu
>> multiprocess, ktery pouze nastartuji ale nejoinu. Vse ale nasvercuje
>> tomu, ze proces je zabyt i kdyz by mel byt daemonem.
Celery (resp. jeho zavislosti) je trochu velke zvire na takovou
drobnost. Co treba mit na tom stroji s standardne pusteny Pyhton
process, ktery se bude starat o ty dlouho bezici ulohy a ten CGI
skript mu jenom preda potrebne vstupni parametry pres
multiprocessing.Queue?
> Aha takze ani daemon = True nepomuze, chjo tak to budu muset udelat jinak.
> Ale zatim me nenapada jak :/
> On Wed 05 Sep 2012 09:56:08 AM CEST, azurIt wrote:
>> Ahoj,
>> proces je ukonceny pretoze jeho parent skoncil (proces web serveru ->
>> CGI skript). Ak si na linuxe, tak toto nie je mozne takymto sposobom
>> urobit (resp. nie je mi znamy sposob). Ine OS neviem.
>>> Od: "Tomas Pelka"<tompe...@gmail.com>
>>> Komu:<Pyt...@py.cz>
>>> Dátum: 05.09.2012 09:51
>>> Predmet: [python] multiprocess problem se sirotkem
>>> Zdravim vsechny,
>>> resim nasledujici problem a verim, ze mi nekdo z vas pomuze.
>>> Potrebuji z cgi skriptu (interpretuje jej jednoduchy httpserver) pustit
>>> dlouho bezici ulohu ale tak abych nemusel volat mutiprocess.join(),
>>> protoze pak stranka zustane viset. Jak jsem zminil pouzivam k tomu
>>> multiprocess, ktery pouze nastartuji ale nejoinu. Vse ale nasvercuje
>>> tomu, ze proces je zabyt i kdyz by mel byt daemonem.
> proces je ukonceny pretoze jeho parent skoncil (proces web serveru -> CGI skript). Ak si na linuxe, tak toto nie je mozne takymto sposobom urobit (resp. nie je mi znamy sposob). Ine OS neviem.
> >resim nasledujici problem a verim, ze mi nekdo z vas pomuze.
> >Potrebuji z cgi skriptu (interpretuje jej jednoduchy httpserver) pustit
> >dlouho bezici ulohu ale tak abych nemusel volat mutiprocess.join(),
> >protoze pak stranka zustane viset. Jak jsem zminil pouzivam k tomu
> >multiprocess, ktery pouze nastartuji ale nejoinu. Vse ale nasvercuje
> >tomu, ze proces je zabyt i kdyz by mel byt daemonem.
>Celery (resp. jeho zavislosti) je trochu velke zvire na takovou
>drobnost. Co treba mit na tom stroji s standardne pusteny Pyhton
>process, ktery se bude starat o ty dlouho bezici ulohy a ten CGI
>skript mu jenom preda potrebne vstupni parametry pres
>multiprocessing.Queue?
> proces je ukonceny pretoze jeho parent skoncil (proces web serveru ->
> CGI skript). Ak si na linuxe, tak toto nie je mozne takymto sposobom
> urobit (resp. nie je mi znamy sposob). Ine OS neviem.
Ukončení parenta rozhodně (ani na unixu, ani na win32) _rozhodně_ obecně
nezpůsobí ukončení childů. Někdo je musí zabít úmyslně. Podezříval bych:
1) multiprocessing
- slouží k dost specifickým účelům a je možné, že všechny procesy
považuje za provázený celek a "by design" je při ukončení hlavního
procesu postřílí (podobně, jako by skončily thready). Určitě bude
zmíněno v dokumentaci.
2) webserver
- je-li přísný a chce, aby po cgi skriptech nic nezbylo
> Celery (resp. jeho zavislosti) je trochu velke zvire na takovou
> drobnost. Co treba mit na tom stroji s standardne pusteny Pyhton
> process, ktery se bude starat o ty dlouho bezici ulohy a ten CGI
> skript mu jenom preda potrebne vstupni parametry pres
> multiprocessing.Queue?
Presne o tomto jsem take premyslel. Budu tedy muset trochu upravit.
můžeš nějak zjistit, jak a čím je ten proces zabit? Třeba přes strace nebo gdb.
Jednoduchý CGI skript, který spustí něco časově delšího přes
subprocess.Popen (ale samozřejmě nejoinuje) a hned se ukončí, mi
funguje a proces na pozadí zůstane běžet. Ale záleží na tom, co s tím
dělá ještě ten server. Můžeš sem poskytnout nějaký konkrétní příklad,
který se dá spustit a vykazuje to tu chybu? Včetně toho, jak přesně se
to spouští. Může to být nějaký detail, okolo procesů v unixu jsou
ještě věci jako process group, připojená konzole, session leader...
Pak se musejí dělat double forky a podobné srandy.
Jinak, abych to shrnul, už se tu asi zmínily všechny obecnější
způsoby, jak to řešit:
1) CGI skript uloží někam informace o tom, že je potřeba něco udělat a
nechá to na něčem jiném. To něco jiného, které tyto joby provádí, může
být:
1.1) nějaký proces, který neustále monitoruje, zda není nějaký nový
job a pokud ano, tak to provede; toto lze zkomplikovat více workery,
chytřejší (push místo pull) detekcí jobu - místo typické databáze lze
použít message brokery (např. RabbitMQ) atd.
1.2) cron script, který dělá to samé jako 1.1), jen to není
dlouhoběžící proces. Tohle je asi nejjednodušší, pokud nevadí vyšší
latence (spouštění jednou za minutu) a pokud ten skript při spouštění
nebere příliš hodně CPU nebo I/O.
1.3) použití nějakého softwaru pro task queue, který je určen právě
pro tyto situace, např. již zmíněné Celery
2) Spouštět proces přímo z CGI skriptu, jak píšeš. Zde bych ale uvedl
pár nevýhod:
- jak je vidět, někdy to nefunguje kvůli nějakým detailům ohledně
ukončování procesů :)
- obecně se nepočítá s tím, že po ukončení zpracování požadavku ještě
něco zbyde. To může přinášet problémy třeba při restartu.
- není kontrola nad tím, kolik takových procesů se vlastně spustí,
mohou dojít prostředky, výrazně to usnadňuje DoS útoky. U řešeních
popsaných v 1) lze relativně snadno kontrolovat, kolik workerů bude ty
joby zpracovávat, případně nějak monitorovat jejich prostředky.
- prostě mi to nepřijde jako elegantní řešení problému, spíš jako hack :)
Zdar
PM
Dne 5. září 2012 9:50 Tomas Pelka <tompe...@gmail.com> napsal(a):
> resim nasledujici problem a verim, ze mi nekdo z vas pomuze.
> Potrebuji z cgi skriptu (interpretuje jej jednoduchy httpserver) pustit
> dlouho bezici ulohu ale tak abych nemusel volat mutiprocess.join(), protoze
> pak stranka zustane viset. Jak jsem zminil pouzivam k tomu multiprocess,
> ktery pouze nastartuji ale nejoinu. Vse ale nasvercuje tomu, ze proces je
> zabyt i kdyz by mel byt daemonem.