Sziasztok!
Me'g egy kis first-world-problem ;) Van egy honlap, amin egy adott funkcio frissit egy adott adatbazist. Ezt a felhasznalo'k interaktivan csinaljak ("click to synchronize with xyz"), e's atlagosan par percig tart egy atlagos 50-100 elembo"l allo atlagos adatbazis frissitese. Egy elem frissitese igy atlagosan 1-2 masodperc, sima u"gy.
Gondoltam, hogy tanuljak is valamit ebbol az egesz vacakbol, csinalne'k egy progress bar szeru" visszajelze'st erre. Kerdes, hogy hogyan lehetne elindulni? Talaltam persze neten jopofa dolgokat, ami sze'pen kijelzi maga't a csikot (igy a frontenddel abszolut nem kell foglalkozni), csak ugye itt a le'nyeg az valahogy lekommunikalja a szerver a klienssel hogy hol tart epp a dolog.
A mostani megolda's nem multi-threaded jellegu, hanem sima brute force (azaz blokkol az oldal letoltese addig az 1-2 percig, kozonseges mezei php bloat sufnituning). Az 1-2 masodperces atlagos update ido"intervallum miatt fokozott sufnituningke'nt a kovetkezo"t is lehetne csinalni. A php-s foreach() ami vegigmegy az 50-100 elemen, egy tmpfs-beli file-ba beirja hogy az adott session, cookie alapjan azonositva, hol tart (mondjuk %d/%d formatumban a /tmp/$SESSION_ID.progress-be), majd egy masik http get/post query egyszeruen visszaadja ezt. Es akkor js-bol kell csak neha meghivogatni ezt...
Barmi otlet ezen felul? ;) Illetve hogyan tudnam pl a fenti jquery:progressbar szkriptet felfejleszteni hogy egy adott url alapjan szamolja ki hogy 37? Es mondjuk lealljon ha ele'r 100-ig (es kiirjon egy linket hogy "click here to continue, whatever")?
thx, A.
- 5985 megtekintés
Hozzászólások
Érdekes, ezek engem is érdekelnek.
- A hozzászóláshoz be kell jelentkezni
Végre egy intelligens "sub"! :-)
--
Tertilla; Tisztelem a botladozó embert és nem rokonszenvezem a tökéletessel! Hagyd már abba!; DropBox
- A hozzászóláshoz be kell jelentkezni
sub
--
blogom
- A hozzászóláshoz be kell jelentkezni
Simán lehet, hogy nem értem jól a problémát, de ha mindenképpen iterálva történik az adatbázisod frissitése, miért nem tárolod magában a db-ben (pl. sessionazonosító mint kulcs mellé), hogy hány rekordból hányat dolgozott fel?
Ezt aztán primitív web svc.-ként (http://hosztod.ahol.hu/getprogress.cgi?sessionid=010101010101010) bármilyen célra leszipkázhatod.
- A hozzászóláshoz be kell jelentkezni
Lenyegeben benne van ez a tarola's, kozvetett modon. Szoval egy query-vel lekerdezheto" hogy mik azok a rekordok amiket frissiteni kell (rendes mtime-jellegu" megoldas). A frissites olyan, hogy napi szinten van csak ertelme, igy alapbol csak azokat kezdi ne'zni ahol 86400 <= time()-mtime, vagy ilyesmi ;)
- A hozzászóláshoz be kell jelentkezni
Arra viszont vigyázz, hogy ha a PHP beépített file alapú session kezelését használod, az lockolja a session-t egészen addig, míg az adatbázis frissítő script fut. Vagyis hiába indítasz egy új kérést mellette, míg az be nem fejeződik, az új kérés nem fut le.
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Aha, erre jo figyelni, koszi, de ``from scratch'' szoktam ezeket csinalni, szoval nem para ;)
- A hozzászóláshoz be kell jelentkezni
Fú, erről a repülő ékezetről vagy szokj le és ne írj semmit vagy írjál rendes ékezetet, de ezt ne.
Második észrevétel: na, pont ez a témakör az, ami miatt rühellem a webes fejlesztést. Volt egy ilyen modulunk, több Excel táblát töltöttek fel, majd az alapján matekolt újra adatokat. Maga az Excel fájlok feltöltése és adatbázisba dolgozása gyors volt, de azok feldolgozása az viszont lassú, akár fél órás művelet is. Probléma volt többek között az is, hogy ekkora futásidő engedélyezése több szempontból sem volt kívánatos. Emiatt született az a megoldás, hogy folyamatosan ment egy AJAX kérés, aminek hatására feldolgozott X elemet az adatok közül, visszaadta, hogy mennyi van hátra, majd a JS újra hívta az egészet, egészen addig, ameddig el nem fogyott.
Maga a megoldás jó szar lett végeredményben. Problémák egyik részének oka ugyan jelen esetben érdektelen, ami viszont lényeges, az az, hogy hálózati problémákra és böngésző fagyásokra roppant érzékeny tud lenni az egész. Na meg ugye maga a hálózat lagjával is lassabb a megoldás, mint tudna lenni.
Ami egy fokkal kulturáltabb lenne, az az, hogy külön process indítása a háttérben, ami DB-be írja valahova az állapotát mondjuk egy PID párosával, te meg azt kérdezgeted időnként.
Még kulturáltabb lenne elfelejteni ezt az egész webalkalmazás nevű szarságot és olyanokra használni a webet, amire kitalálták.
----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Fú, erről a repülő ékezetről vagy szokj le és ne írj semmit vagy írjál rendes ékezetet, de ezt ne.
+1
- A hozzászóláshoz be kell jelentkezni
Van egy halom, megoldás erre, egyik jobb/rosszabb mint a másik.
Egy ilyen feladatot mindenképpen háttérben érdemes elvégezni szerintem, én az ilyet nem bízom a véletlenre. Egy cronjob kell csak neki ami percenként lefut, megnézi, hogy van e új feladat számára, ha igen, akkor action. Persze írhatsz C,C++,Java,stb -ban valami mini szerver progit ami elindítja a feldolgozandó php-cli scriptet a háttérben. A szerver progit pedig local socket-en szólítod meg a hívó php-dból.
A progress bar pedig annyi, hogy pl ajax-al kérdezgeted le mi hogy hol áll éppen, vagy frissíted az egész oldalt vagy iframe (nem szeressük itten a framekat)
Van még ennél jobb módszer ami realtime módot hoz létre, viszont kompromisszumokkal jár. A kliens oldalon azaz a weboldalon egy socket klienst hozol létre. Html5-nek ugyebár van már javascriptes megoldása erre ha jól rémlik. Még nem próbáltam, de ami késik nem múlik. Illetve ha azt akarod, hogy mindenkinek fusson, akkor flash a megoldás. Nem is kell nagy cucc, egy kicsi akár 1px x 1px-es swf ami ott fut neked a háttérben, elindítja a socketet és majd javascript függvényeket hív meg az oldaladon ami frissíti a html progress bar-t.
A szerver oldalon pedig kell egy socket szerver amin keresztül le tudja kérdezni a helyzetet. Most már más kérdés, hogy a socket szerver dolgozza e fel az adatokat, vagy rajta keresztül egy php script, illetve az is lehet, hogy minden ilyen munkafolyamatra egy külön socket szervert futtatsz (de teljesítményben annyira nem biztos, hogy jó, illetve nem is szép)
Így hirtelenjében ezeket szedtem elő gyorsban.
- A hozzászóláshoz be kell jelentkezni
+1, nagyjából ez a megoldás módja.
DB-ben queue van tulképp, amit egy cronjob percenként felszed. Ha valami javulás áll be az adott job állapotában, azt a DB sorában jelzed, ajaxból meg azt kéred le (akár long pollinggal), PHP esetén a többi nemigen jön szóba.
A long polling megoldás lényege:
1) elindít a kliens egy ajax kérést a szerver felé, nézze má meg, hogy áll a job, legutóbb így és így állt
2) szerver megnézi, hogy áll a job
- HA változott, visszaszól az új értékkel
- HA nem változott, elindít egy timer-t (pl. 30 mp), meg egy ciklust
Ebben a ciklusban a 30 másodperc alatt mondjuk megnézi 5x, változott-e valami
HA igen, visszaszól
HA timer leáll, visszaszól, hogy nem változott semmi
3) kliens amint megkapja a választ, új AJAX kérést indít.
HA nem feltétel a PHP backend, akkor van még rengeteg megoldás az ilyenre, a socket.io honlapján egész szépen összeszedték őket, de még ezen felül is van pár.
Amúgy meg: a progressbar jól hangzik, de 1-2 percnél inkább egy FB-szerű notification-t érdemes kirakni, ahogy a torrent kliensek is csak csilingelnek ha lejött az ubuntu, a progress ebben a kategóriában nagyjából lényegtelen.
Persze ez csak akkor igaz, ha van mit csinálni, de a végén tényleg érdemes csilingelni, mert 1-2 percig minek nézze a progress bar-t, el fog lapozni másik tabra/programra/stb.
- A hozzászóláshoz be kell jelentkezni
Mint üzemeltető csak azt tudom mondani, hogy a vakus taknyolást ne, mert jön majd a főnök, hogy a zandroidos telefonján miért nem megy. Vagy az almáson (bár azon lehet hogy van vakku).
- A hozzászóláshoz be kell jelentkezni
vakku? ez alatt a flash-t értetted? Én már kerülöm egy jóó ideje. Fostalicska egy dolog.
Amúgy én csak felsoroltam a lehetőségeket.
- A hozzászóláshoz be kell jelentkezni
Csak hogy legyen a JS oldalára is megoldás: http://jsfiddle.net/WLpfJ/
(please note: ha nem muszaj, ne csinald meg modalisra, a delikvens hadd csinaljon az oldalon amit akar, csak sajat kodot butitottam vissza a peldadra es az volt modalis mas okbol)
- A hozzászóláshoz be kell jelentkezni
Koszi, ezt megnezem alaposabban is! Nem vagyok egy nagy JS-guru (sot), szoval meg lehet hogy lesznek kerdesek...
- A hozzászóláshoz be kell jelentkezni
Engem hasonló érdekelne. Adott egy MySQL adatbázis, amiben pár táblában frissülnek adatok. Ezeket szeretném minél frissebben és hamarabb kiíratni a felhasználó számára. Természetesen úgy, hogy ne kelljen "reload"-ot nyomkodni. 1s-ként frissíteni nem akarom a teljes lapot. Olyan megoldást keresek ami kevesebb erőforrást fogyaszt. A lapon lenne dinamikusan változó adat, pl. szöveg, szemafor (piros/zöld), egyéb folyamatjelző, pl. progressbar.
- A hozzászóláshoz be kell jelentkezni
Koszi mindenkinek a kommenteket! Igen, az biztos hogy szerveroldalon lenne ezt erdemes igazan kulturaltan csinalni, valahogy. De a problema az tenyleg luxus-kategoria (abszolut nem kritikus megcsinalni, senkinek nem lesz ettol jobb), de talan ezert is jobb, igy kikiserletezni ezeket, hatha 1x "igazibol" is szukseg lesz ilyesmire...:) Vagyis igazabol ne legyen, persze (a webet hasznaljak arra amire kitalalatak, ahogy fentebb is irtatok), de ha a kereslet-kinalat ennyire eltolodott erre, akkor ez van :/
- A hozzászóláshoz be kell jelentkezni
Faék megoldás, de egy nálam is felmerült feladatra szerintem így fogom megcsinálni:
Több felhasználós webfelületen elindítanak egy feladatot, ami bekerül egy "cronjob" sql táblába. Ezt az sql táblát egy script időnként megnézi és ha van feladat, végrehajtja + az egyik (pl. status) cellába 0-100-ig visszaírja, hogy hol tart.
Az előbbi webfelületen lesz egy iframeben lévő php, ami betölt egy valami.php?cronjob=$azonosito oldalt. Ez az oldal az átadott azonosító alapján sql-ben kikeresi az adott cronjobhoz tartozó status cellát. Az általatok linkelt (meg neten fellelhető valamennyi) példával + az sql-től kapott számmal kirajzolom a jóembernek, hogy lássa, hol tart a folyamat. Bár ennél a szintnél már az is elég, ha kiírom számokkal, hogy hány %.
Az iframeben lévő php fejlécében html tagokkal megadom, hogy 1-5 másodpercenként frissítsen rá. Ha a user bezárja a böngészőt, lelép, stb senkit nem zavar. A cronjob dolgozik a háttérben.
Ha 1 user egyszerre csak 1 cronjobot indíthat, akkor még egyszerűbb. Lekérdezésnél nem a cronjob azonosítóját kell átadni, hanem az user nevét. Így bármikor visszamegy, rábök a cronjob status lekérdezésre, a neve alatt futó/nem futó cronjob statuszát kapja vissza.
Ha a cucc végigment, a 100%-t át lehet írni pl. done -ra, és a lekérdezésnél berakni egy "korábbi sikeresen lefutott cronjobok" linket, ami csak a kész cronjobokat listázza ki amolyan előzményként.
- A hozzászóláshoz be kell jelentkezni
sub
- A hozzászóláshoz be kell jelentkezni