Javascript aszinkron iteráció
Sziasztok,
egy olyan kérdésem lenne felétek, hogy NodeJS-ben szerintetek mikor van létjogosultsága egy feladatnak aszinkron feldolgozni, illetve mikor jobb a hagyományos szinkron megoldás?
Például adott egy for ciklus ami a példának okáért mondjuk sima összeadásokat végez egy tömbön. Ezt érdemes-e aszinkronra ki szervezni?
Mi az a határ amikor valamit szinkron vagy épp már aszinkron valósítanátok meg? A lekérdezés az adatbázis felé már egyértelműen aszinkron kategória, de az alatt hol lehet az egyensúly?
Ti hogyan vélekedtek erről?
■ egy olyan kérdésem lenne felétek, hogy NodeJS-ben szerintetek mikor van létjogosultsága egy feladatnak aszinkron feldolgozni, illetve mikor jobb a hagyományos szinkron megoldás?
Például adott egy for ciklus ami a példának okáért mondjuk sima összeadásokat végez egy tömbön. Ezt érdemes-e aszinkronra ki szervezni?
Mi az a határ amikor valamit szinkron vagy épp már aszinkron valósítanátok meg? A lekérdezés az adatbázis felé már egyértelműen aszinkron kategória, de az alatt hol lehet az egyensúly?
Ti hogyan vélekedtek erről?
Párhuzamosság
Ha több felhasználó használhatja párhuzamosan az alkalmazásodat, akkor legyen minden aszinkron, ami ezeket kiszolgálja (mondjuk az alkalmazás elindulása felépülhet szinkron kérésekből, de utána legyen minden aszinkron). Ez azért fontos, mivel a Node.js kód egy szálon fut, azaz ha egy felhasználónak a kérését szinkron szolgálod ki, addig nem tudsz más felhasználót kiszolgálni, annak bármilyen kérését feldolgozni amíg a szinkron esemény nem végzett.
Egyszerűbb úgy megfogalmazni,
Igazságosan
Hát amikor a Windows vagy az OSX valami háttérbeli indexelést csinál, azt se igazságosan teszi, mert nem oda ütemezi a CPU-t ahol nekem van rá szükségem.
off:
Már persze attól függ, mit tekintünk igazságosnak. Pl. ha veszek egy tábla csokit, és abból csak a gyerekek kapnak az igazságos? Csak mert én nem kaptam. Vagy ha mindenki kap egyenlő szeletet (de mondjuk én nem szeretem a csokit). Vagy mindenki a súlyának / korának / magasságának stb. megfelelő méretűt kap az igazságos?
Az igazságos szinte semmilyen
Köszönöm gyors
Igen ezzel tisztában vagyok. Arra akartam kitérni, hogy minden részt érdemes-e aszinkronra kiszervezni, vagy van annyira rövid a szinkron kód futási ideje, hogy szinkronban oldjam meg.
Hozok is példát:
Adott egy rendelés beszúrása mongo-ba. A rendelés úgy épül fel, hogy tárolva vannak a rendelés tételei illetve a végösszeg. Az egyszerűsített séma:
Azt tudom, hogy ha ezt for cikklusba szervezem blokkolok.
A kérdésem az, hogy ez egy nagyon rövid idő. Azt is tudom, hogy sok kérésnél összeadódhat.
Az ilyent is érdemes már aszinkronra kiszervezni?
Köszi.
Azt tudom, hogy ha ezt for
A kérdésem az, hogy ez egy nagyon rövid idő. Azt is tudom, hogy sok kérésnél összeadódhat.
Az ilyent is érdemes már aszinkronra kiszervezni?
És hogyan tudnád ezt úgy megoldani hogy nem blokkolsz? A ciklusnak előbb utóbb úgyis le kell futnia, és ezt nem igazán tudod nem blokkoló módon megtenni, mert szükséged van a számításhoz a CPU-ra. Ha pedig mondjuk feldarabolod kis részfeladatokra, és azokat
nextTick
-en hajtod mondjuk végre, akkor a kódod sokkál tovább fogja a CPU-t igénybe venni (akár többször annyi ideig is), mint eredetileg, úgyhogy nem igazán takarítáttál meg vele semmit, legfeljebb még X felhasználóval többet várakoztatsz (mivel azok sem jutnak CPU-hoz, csak jóval később).Köszönöm. Erre voltam
Erre voltam kíváncsi. Hasonlóan vélekedem én is a kérdésről, de szükségem volt a megerősítésre.
A lekérdezés az adatbázis
CPU
Aha
Vegyünk egy PHP példát (ezt ismerem), a dokumentációból másoltam:
printf("Select returned %d rows.\n", mysqli_num_rows($result));
/* free result set */
mysqli_free_result($result);
}
Tehát, ha jól értem, akkor a CPU a fenti mysql kérés idejére eldobja a kapát, kaszát ("Mert addig úgysem tudsz tovább haladni a kiszolgálással"), és nem tud mást kiszolgálni ("amíg nem kapod meg az adatot, és addig a CPU csinálhat valami mást is")?
Szeretnék most már ennek a kérdéskörnek a végére járni.
Te vagy a futtató rendszer
A Node.js-ben írt webszervered egy szálon fut. Azaz egyszerre egy felhasználó kiszolágálásával tud törődni. Van benne egy Event Loop, amibe beérkeznek az események, és a beérkezés sorrendjében feldolgozhatóak. Ha több felhasználóval akarsz foglalkozni, akkor addíg, amíg várakozol, beteszel egy elemet az EL-ba, majd visszatérsz. Ekkor átadódik a vezérlés a következő elemnek az EL-ban. Ha az történetesen egy kérés, akkor azt is elkezded feldolgozni. Ha azzal megvagy, akkor kivesz egy újabb eseményt stb. Ha az történetesen a te adatbázislekérdezésed válasza, akkor a callback függvényedben folytatódik az első kérés kiszolgálása.
Ha nem maradt több callback az event loopban, akkor a program végetért.
A felsoroltak a programozó
stabilitás, memória igény, sebesség
Mivel sokkal nagyobb a programozó szabadsága, mint más interpretált nyelvekben, ezért lehetséges nagyobb optimalizációt elérni (viszont emiatt nagyobb a felelősség a programozón). Az alkalmazások a kicsiny mag miatt kevesebb memóriát fogyasztanak (egy egyszerűbb alkalmazás nem fogyasz többet 10-20 MB-nál).
Node.js-hez elérhető rengeteg modul, és egyszerű hozzá C++ felületű kiegészítőt kapcsolni a sebességkritikus részekhez.
Akkor eléggé szembemegy a
Gyakorlatilag mindent az eseménykezelőn keresztül vezérelsz, azaz aszinkron programozol. Ez milyen előnyökkel jár a programozó számára?
Ez milyen előnyökkel jár a
Nem keltik fel háromkor, hogy összedőlt az oldal a forgalom alatt.
Ennyi?
Ja.
Pályafutásod alatt téged
Én nem is használok már
Ezen rugózok már itt mióta...
És mióta mondjuk, hogy ez egy
vert.x?
Mivel győznél meg róla?
Nem akarlak meggyőzni
jQuery
Én is csak egyszer
Én lustaságból használom,
Szeretnék most már ennek a
Akkor tisztázzuk egyszer és mindenkorra:
Többszálú architektúrán az ütemezést a rendszer végzi, ezért minden szál annyi időt kap, amennyit osztanak neki, bízhatsz a szekvenciában, mert az I/O hívások idejére a szál alszik, cserébe sok szál esetén a statikusan foglalt stackek alatt elfogy a memória.
Egyszálú architektúrán nem okoz gondot a stack helyigénye, cserébe az ütemezést kézzel végzed, és megszűnik a szekvencia, mert az I/O hívások előbb visszatérnek minthogy eredményük volna.
Előnyök-hátrányok, ki-ki mérlegeljen.
Megoldás: a stacket dinamikusan foglaló rendszer kifejlesztése.
Bonthatjuk a sört?
A PHP is egy szálon fut, de
Apache
Dehogy fut.
Szalad.
A PHP alkalmazás is több
(Kocog.)
Lassan járj, tovább érsz : )
Aszinkronitás
MadBence épp nemrég jelentetett meg egy hosszabb cikket az aszinkron programozásról, ha elolvasod a konklúziót, láthatod, hogy még nincs jó megoldás a felmerülő problémákra. Emiatt az ilyen aszinkron programozási rendszerek, pl. a Node.js játékszernek jók, de valós életbeli projektek kivitelezésére egyelőre alkalmatlanok.
Valós életbeli
Nézted azokat a linkeket?
Microsoft - Uses node.js internally
Walmart - nincs is rajta a listán
Linkedin, Voxer - mobilalkalmazásokat szolgálnak ki
Semmi konkrétat nem tudunk meg ebből a listából, azt sem tudjuk, mikor frissült. Ez alapján eldönteni, hogy mennyire használják valójában, nem lehetséges.
De úgy is lehetne fordítani, hogy van itt száz cég, aki használja, de van egymillió, aki meg nem.
Hát, nem túl komolyak. Te
Te csak komoly alkalmazásokat / weboldalakat szoktál fejleszteni?
History
És szerinted ez az adott cégnek nem létfontosságú?
Why Walmart is using Node.js
Attól még, hogy egy API nem úgy működik, mint a PHP, vagy bármi más nem feltétlen rossz. Más szemléletet igényel, ez tény, de máshogy is működik. Próbáltál már Haskellben, Erlangban, Goban, Pytonban alkalmazást fejleszteni? Mind más szemléletet igényel.
Emiatt az ilyen aszinkron
Ezt erősen kétségbe vonom. Vannak jó megoldások aszinkron programozás terén, pl ezt: https://github.com/caolan/async érdemes nézegetni. Ezen kívül még van egy rakat, köztük olyan is, ami nyelvi elemekként definiál dolgokat (ahogy nézem ez utóbbiak már nem elterjedtek, mert kényelmetlen a telepítésük). Egyszerűen utána kéne olvasni... (Ez inkább 1-2 éve volt vita tárgya nodejs terén, mostanra szerintem már lecsengett...)
Thread-eket szintén implementálta valaki nodejs-hez. A socket.io-val egyszerűen lehet chat alkalmazásokat írni, vagy bármi olyat, ami folyamatos kapcsolatot igényel. Ezen kívül láttam már olyat is, hogy drivert írtak valamilyen beviteli eszközhöz nodejs-ben. Körülbelül egy év alatt többet fejlődött nodejs, mint a php 10 év alatt, köszönhetően annak, hogy alacsonyabb szintről indul. Elég jól eltalálták, hogy mi az, amire szükség van, és mi az, amit jobb, ha a közösség valósít meg úgy, ahogy neki tetszik. Ahol nagyobb a szabadság, ott általában megjelennek a kreatív emberek, és alkotnak...
szerk:
Közben elolvastam "MadBence" cikkét is, tetszik, nagyon átfogó. Én nem úgy fogalmaznék, hogy nincs igazán jó megoldás, hanem inkább úgy, hogy mindegyik bemutatott megoldása használható aszinkron kérésekhez, és mindenki választhat a saját szájíze szerint... Általában nodejs-ben ha van egy problémád, akkor az az szokott lenni, hogy melyik létező megvalósítást válaszd, nem pedig az, hogy hogy érdemes implementálnod a megoldást...
Én is hasonló kép vélekedek
Én pl. azért választottam projektem alapjául, mert adatbázisként elve mongodb-t használok és a JSON formátum miatt eléggé kényelmes JS-ből használni.
Továbbá a Push-os értesítéseket websocket-en keresztül eléggé könnyen meglehetett valósítani. A template-eim egyaránt működnek szerver és kliens oldalon is.
(ECT) Ezért a fő layout-on kívül szinte minden mást már a böngészőben képezek le.
De ami még nagyon megfogott a NodeJS-ben az npm. Tetszik a csomag kezelője, de a közösségi plugin-ek minősége sok gondot tud okoz. Erre valami minősítési rendszert kidolgozhatnának.
Hát nekem az a minősítési
A postgresql-hez meg elvileg lehet feltenni javascriptet is procedurális nyelvnek, szóval relációs adatbázissal is megoldható, hogy csak js-t használjon az ember. :-) Adatbázist is a munka jellegéhez kell választani. Ha jól emlékszem a mongo olyan, hogy a vátozásoknál egyedi azonosítót tesz be. Az pl nagyon tetszik, history szempontjából marha jó megoldás... Dokumentumok tárolására jó a mongo, ahol viszont minden mindennel összefügg, ott jobb egy relációs vagy gráf adatbázis. Tényleg mindennek megvan a maga helye, komolyabb projekteknél akár többféle adatbázist is lehet egyszerre használni, mert elég jól ki tudják egészíteni egymást.
Köszi a tippet. Már én is
Már én is elkezdtem gyűjtögetni a kritériumokat. Én már az utolsó módosítás idejét is nézem. :)
Sokszor jutottam oda sajnos, hogy volt egy nagyon várt funkcionalitás, de erősen hiányos volt és ki kellett egészítenem a kódot. De azt tapasztalom, hogy ha még kérek is pull request-et, nagyon eltudják hagyni a kisebb projekteket az emberek és van, hogy fél éve mire egy pull request-em érvényesül.
Ez az egy gondom van a kis kódbázissal, de amúgy én is ezt a megoldást kedvelem.
Ami viszont bosszantó tud lenni azok az elfedő nyelvek. CoffeScript és társai. Erősen unszimpatikusak az ilyen "ruby similar" nyelvek. A typeScriptel még kibékülnék (tudom, kinek a pap, kinek a paplan), de ezek sokszor megnehezítik a hiba keresést.
Nekem is van API rész az oldalban ami külön instance-on fut.
Arra jelenleg most restify-t használok. Szeretem a változatosságot, a hagyományos kiszolgálásra meg természetesen express-t. A restify-t express kompatibilis így nem nagyon kellett tanulni és hála az égnek eléggé jó a dokumentációja.
Igen. A mongodb-t nagyon szeretem, hála az égnek a mennyiség jelen van a komplexitás felett, így viszonylag egyszerű sémám van. Szeretem még az id-ket,mert tartalmaz időbélyeget, illetve könnyen kérhető egy ID tetszőleges célra.
Illetve GridFS-t használok még ami a Mongo-t érinti, ott tárolom a képeket. Ami meglepően gyors és NodeJS alatt tudom "streamelni" is közvetlen mongo-ból.
Nem tudom mennyire függ a mérettől, de eddig alig tapasztalok overhead-et a natív fs-hez képest. Illetve a mongo klaszterezésével és backup-jával az állományaim is biztosítottak.
Én már az utolsó módosítás
Ja azt szoktam én is, meg hogy az issue listából mennyi a megoldott, stb...
Azt hiszem vannak már ezekhez is debuggerek, de én a javascriptet szeretem... A TypeScript azért lenne jó, mert js kompatibilis visszafele, a coffeescripttől meg feláll a szőr a hátamon... Mindkettőt megnéztem, meg megtanultam olvasni, de valahogy egyikben sem szívesen fejlesztenék, amíg nem az a hivatalos js szabvány...
A restify-ra azt írták, amikor legutóbb néztem (fél-egy éve), hogy fele olyan gyors, mint az express az express resource-al, azért írtam fel magamnak inkább ezeket... Egyébként mindkettő ugyanazt tudja...
Nem tudom mennyire függ a mérettől, de eddig alig tapasztalok overhead-et a natív fs-hez képest. Illetve a mongo klaszterezésével és backup-jával az állományaim is biztosítottak.
Na ez tök jó, nem tudtam, hogy mongoban is lehet fájlokat tárolni. Fájl tárolásra tipikusan a key-value adatbázisok a legjobbak, mint pl riak vagy redis... Ezek baromi gyorsak... Hmm ahogy nézem inkább kis fájloknál jók, 50mb-nál nagyobbakra nem ajánlják. Azt is írják, hogy a mongo 2gb adatbázis méretnél összeomlik. :-) Egyik sem tökéletes ilyen célra...
100Gb
Passz, én nem használtam még,
Hmm ahogy nézem inkább kis
Nem tudom mennyire van jelentősége, mert un. "chunk"-okban tárolja az adatokat. Ezért is tudom kiválóan stream-elni nodejs-ből.
Két kollekció van. Az egyikben a fájl adatok, md5 sum, content-type, fájlnév, meta adatok stb... A másikban meg a fájlhoz tartozó chunk-ok. Ezeknek az átlag mérete 4Kb körüli ha az emlékeim nem csalnak. De talán beállítható.
Az egyik verzióban tényleg volt valami gond, de csak a 32 bites változattal. Engem meg nem érint. :)
Viszont jó, hogy könnyen tudok a fájlok mellé plusz "meta" adatot tárolni. Pl.: Milyen változat, melyik felhasználóé, stb...
Ezen téren is eléggé kényelmes.
Infó: Mongo GridFS