webes feluleten egy lassan valtozo bitkolbaszt mutatni hogyan?

 ( sj | 2013. augusztus 18., vasárnap - 22:40 )

Szoval adott egy admin felulet, egy dashboard, whatever, amin Bela bepotyog par adatot, majd ranyom a mehet gombra. A hatterben erre elindul egy cli program, ami a parameterek alapjan jo sokaig dolgozik. 2 problema van: nem biztos, hogy par sec alatt (ameddig a user turelmesen hajlando varni az eredmenyre) lefut, hanem a futas ideje akar percekben is merheto. Tehat a usert valamivel pl. bitkolbasz szorakoztatni kell, amig a program dolgozik.

A masik problema, hogy ez a binaris cli program par szamot ad vissza a vegen, pl. hany rekordot dolgozott fel, stb, ill. menet kozben is tud kiirni szamokat, vagy pottyoket, ahogy halad szepen az egymast koveto adatok feldolgozasaval.

Szoval mig potyogtem ezeket be, az jutott az eszembe, hogy egy lassan (akar percekig is eltart) valtozo %-os bitkolbaszt kene mutatni a usernek, amig dolgozik a program. Ezt hogyan csinalnad meg? A webes felulet php-t es javascriptet(+jquery) hasznal(hat).

UPDATE: a kedves juzer szeretne, ha nem kellene 1 oran keresztul egy csigalassan valtozo bitkolbaszt neznie, hanem elinditja, megunja, elnavigal az oldalrol, pl. nez egy kis youtube-ot, majd visszajon kesobb megnezni, hol tart a bitkolbasz? Sot, a kereset tovabbolvasva egy queue-t kene kezelni, mert a cli egyszerre csak 1 adathalmazt kepes kezelni, a kovetkezohoz uj parameterezessel ismet el kell inditani.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Ajax mond neked valamit? (jquery-t nem igazán ismerem, abból nem tudom, hogyan lehet ajaxos működést megvalósítani, csak azt tudom, hogy van benne)
Vagy ennél bővebb tipp kellene?

Ajax mond neked valamit?

az osrobbanasig azert ne menjunk vissza :-)

Diktatorok kezikonyve

Akkor legyen WebSocket :)

Amúgy: felépítesz egy Ajax kapcsolatot, aminél a szerver simán vár, amíg a másik thread/process/akármi nem küld egy signalt (pl. php-nél ez akár egy flock híváspárral is megoldható, a producer WRITE lockol, a consumer READ-el), ekkor visszaküld pl. egy OK-t. A böngészőben meg egy JavaScript frissíti a százalékmutatót mondjuk 10-el (vagy amennyire terhelni akarod a szervert :) ), aztán újrakapcsolódik. Pollozásos, csúnya, de működik. Alternatíva: Comet.

BlackY

Van valami elnevezése annak, amit a gmail is használ (long poll??), ami úgy általában egész elviselhetőnek tűnt anno.
Ebben az esetben számomra inkább az lenne a kérdéses, hogy a webes felület hogyan tudja "megszólítani" a háttérben futó folyamatot és elkérni tőle, hogy hol tart.

Gányolásképp mondjuk a szerver oldalon megjegyezni az indított processzhez tartozó pid-t és x másodpercenként küldeni neki egy USRx szignált, aminek hatására valahová lerakja, hogy épp hol tart, a PHP program kiolvassa ezt az értéket és megmutatja a felhasználónak akár numerikusan, akár "bitkolbász" formában.

kozben azon gondolkoztam, hogy tkp. egy cli program es a php/ajax kozotti "ipc"-t kene megvalositani. Eloszor egy perzisztens taroloban gondolkoztam (pl. adatbazis), aztan meg memcached-ben, de a file, amit irtal, tunik a legegyszerubbnek, hogy a cli program tudositani tudjon az allapotarol, hogy eppen hol tart.

Meg ugye az is nehezitett palya, hogy az ajax hivas meghiv mondjuk egy php scriptet, ami exec*/system/whatever hivassal elinditja a cli programot, hogy meddig fogja futtatni? Vagy az ajax resz csak az allapotfrissiteseket pollozza, es meg a hivo weboldalnak kellene mondjuk a backgroundba (&) tenni a cli programot.

Az meg ujabb bukkano, hogy az is milyen fancy feature lenne, ha a user, egy gombra bokve meg is tudna olni a cli programot, igy abortalva a feldolgozast.

Nezegetem meg az ustokost...

Diktatorok kezikonyve

A proc_exec környékén nézelődnék, azzal elindítod a processzt, és közben azt csinálhatsz, amit akarsz (pl. olvasgathatod a standard out-ját, írhatsz az in-jére, amikor meg van tipped, hogy haladt valamennyit a program, akkor szinkronizálsz a másik php processzel, hogy az visszaszólhat a usernek).

Egy shutdown handler (vagy ilyesmi a neve) és a proc_kill megoldja, azt nem tudom, hogy XHR-nek van-e close funkciója (mármint ami tetszőleges állapotban megszakítja a lekérést), a böngészőnek viszont stop gombja mindenképp van.

BlackY

Bocs, alig ismerek itt valakit, nem tudom, hogy ki mit ismer. :)
(bár egy ősrobbanás... hmmmmm... :D)

Akkor viszont a kérdést nem értem. Konkrét kódot szeretnél látni? Úgy másfél éve próbálgattam az ajaxot, akkor csináltam valami ilyet, ha még megtalálom a kódot majd elküldöm vagy berakom ide, de ennek elég csekély az esélye.

akkor ajax es bitkolbasz mutatas, amig a hatterfolyamat veget nem er. ertelmes kerdesre ertelmes valasz.

btw. a bitkolbasz is tapasztalatok alapjan a "hasznalhatatlanul lassu" kategoriaba fogja sorolni az alkalmazast, maximum 3sec kenyszeru varakozas utan...

--
A gyors gondolat többet ér, mint a gyors mozdulat.

Az alkalmazás mindenképp lassú, akkor meg már jobb, ha van valami visszajelzés, hogy "dolgozom, ne bökdösd a submit gombot, attól nem lesz gyorsabb". Bár erre a legegyszerűbb disabled-re állítani a gombot :) Esetleg ráírni, hogy "Feldolgozás, kérem várjon..."

BlackY

igy van. Lesz egy dolgozom, varjal man turelmesen felirat az obligat be ne csukd az ablakot, stb. szoveggel. Ez nem egy 3 sec alatt lefuto dolog lesz...

UPDATE: a kedves user megis szeretne elnavigalni az oldalrol, sot, a kerest tovabb olvasva egy queue-t kene kezelni. Azaz bela megad tobb adathalmazt (a cli egyszerre csak egy adathalmazt tud kezelni, a kovetkezohoz mas parameterezessel ujra el kell inditani). Ez egy kicsit mas megvilagitasba helyezi a dolgot...

Diktatorok kezikonyve

Nem tudom milyen szerver komponensek vannak (pl php-n kergeted át). Ha nem valami veszett haproxy<->nginx<->php-fcgi páros amik szeretnek bufferelni (van async módjuk ami pl jó erre, de performance is drágább ilyenkor), akkor php -n keresztűl, proc_open-el a háttérben tudod úgy futtatni a cli alkalmazást, hogy használhatod az általa nyújtott pipe-okat (stdin, stdout, stb:D). Ha a cli alkalmazás flush-ol, akkor tudod parse-olni az általa adott sort, amit egy long polling ajax híváson keresztül át tudsz passzolni a böngésző irányába. Így real-time statot kaphat a user a cli program futásáról.
Ugyanez persze megoldható minden mással is, nem csak ebben a felállásban (de ha jól emlékszem és az amire gondolok, akkor te php-t használsz)


// Happy debugging, suckers
#define true (rand() > 10)

default nginx+php-fpm-et hasznalok, de apache+mod_php(?) eseten is jo lenne mukodnie.

Ha a cli alkalmazás flush-ol, akkor tudod parse-olni az általa adott sort, amit egy long polling ajax híváson keresztül át tudsz passzolni a böngésző irányába

ez tetszik, csak attol felek, hogy a php fogja megolni a dolgot, ha a max_execution_time alatt nem fejezodik be a program.

Diktatorok kezikonyve

Ezt én belső felhasználásra parasztosan oldottam meg, a parancs outpuja bekerül két pre közé. Persze annyi nem árt ha nem nagyon puffereli az outputot.

Kereskedelmi cuccba viszont kellhet a mókusvakító futófény vagy valami.

Egy sima animált GIF?

worst case ez is lehet(ne), de a fentebbi problemakat ekkor is meg kell oldani...

Diktatorok kezikonyve

a cli program beírja folyamatosan a % állást egy fájlba
vagy beírja adatbázisba
vagy socketen keresztül kérdezed le tőle

ezeket pedig php-val gyerekjáték lekérdezni amikor a user odanavigál, illetve ajax-al frissítgetni
ha mindenképpen real time kell, akkor vagy html5 -ös sockettel folyamatosan szinkronizálni, vagy flash-ban socket client-ezni.

esetleg java applet-ben, bár ettől kiráz a hideg :)

igen, ahogy gondolkodtam meg a dolgon, valoszinuleg az lesz, hogy a php nem fog processzt inditani, hanem egy adatbazis tabla lesz a queue, benne a parameterekkel. Azt pedig majd egy cron job nezegeti, hogy van-e job a queue-ban. Ha van, akkor csinal egy lock file-t, es szepen vegigmegy a job-okon elinditva a cli programot. Az pedig mondjuk 5 sec-enkent frissiti a tablaban a statuszt., amit majd ajax-szal lekerdezek.

Kossz mindenkinek az egyuttgondolkodast.

Diktatorok kezikonyve

A csilli-villi részhez: http://jqueryui.com/progressbar/#label