node.js - callback visszatérés "beágyazott" callback visszatérési értékével

Sziasztok,

egy egyszerű view helperen dolgozok, ami a paraméterekben kapott kulccsal
a blokkban található template részletet memcache-be rakja, majd következő
alkalommal az adott részlet legenerálása helyett onnan szolgálja ki.

Az egyetlen probléma vele az, hogy a node.js aszinkron működése miatt ugye, a külső
függvény hamarabb visszatér, minthogy a belső függvény lefutna, így lényegében
mindig null-al tér vissza.

Van erre valakinek ötlete, aki jártasabb a node.js-ben és Javascriptben?

Előre is köszönöm!


hbs.handlebars.registerHelper('cache', function () {
  var context = this;
  var options = arguments[arguments.length - 1];
  var html = null;
  var cacheKey = '';

  for(var i = 0; i < arguments.length - 1; ++i) {
    cacheKey = cacheKey + arguments[i];
  }

  memcached.get(cacheKey, function (err, data) {
    if (data) {
      html = data;
    } else {
      html = options.fn(context);
      memcached.set(cacheKey, html, 0, function (err) {});
    }
  });

  return new hbs.handlebars.SafeString(html);
});

Hozzászólások

Cache kapjon parameterul egy fuggvenyt, amit return helyett majd meghivsz html parameterrel, ebbe a modszerbe Tagabb ismerettsegi koromben belebotlasz node.js-ben...

----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"
--> YouTube csatornám

Igen, ez volt az első gondolatom, de sajnos jelen esetben a 'cache', illetve bármilyen tetszőleges néven beregisztrált Handlebars helper fixen az options változót, illetve a template-ben átadott paramétereket kapják meg, így nem igazán lehet neki átadni callback-et.

Így néz ki egyébként template oldalról a dolog:

{{#cache 'cache' 'key'}}
valami
{{/cache}}

A helper ilyenkor a Handlebars-tól a következő paramétereket kapja meg: 'cache', 'key', options.

Én kicsit más szögből közelíteném meg a problémát, méghozzá megkérdőjelezném, hogy van-e értelme a template-eket eltárolni memcached-ben? Használod más alkalmazásban?

Az alapján amit írtál én nem foglalkoznék külső szolgáltatásokkal, hanem hagynám hogy az alkalmazás memóriájában gyűljenek a cache-ek. Nagyon minimál megoldásként egy sima objektumba, vagy esetleg görgetnék egy néhány soros modult hozzá, ha kell elévüléssel, vagy a cache méretének kordában tartásával foglalkozni.

Vannak is már jó megoldások, amik nem csak aszonkron módon hívhatók: https://www.npmjs.com/package/node-cache

"kérdést továbbra is jogosnak tartom"

Kérdésedre kérdéssel válaszolok. :)

Önnek adott egy nagy terheltségű többszerveres környezete, 3 alkalmazásszerverrel, mindegyik a fenti view cache-elős kódrészletet alkalmazza. Kérjük jelölje meg a helyes választ:
A, az alkalmazás szerverek tárolják maguk a cache adatokat, többszörösen redundánsan
B, az alkalmazás szerverek egy erre a célra dedikált cache szerverre dolgozzanak

Ezt:
return new hbs.handlebars.SafeString(html);

Miert nem teszed be a memcache.get -be? Sebessegben lassu?

Mert ha igen, akkor ajanlom figyelmedbe az async lib-et (waterfall azon belul).
Vagy pedig promise-ban melyedjel el.

Latni kene a teljes kodot.

De megmondom oszinten a hup.hu nem a legmegfelelobb platform.
Szanj ra kb. 2 orat fogalmazd meg a kerdesedet rendesen (egyszerusitett peldaprogramokkal),
es tedd fel a stackoverflow-ra.

En igy szoktam ... :)

---
Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Sehogy. De nem is kell, mivel a belso utan mar nincs programlogika.
Ezert kerdeztem, hogy mennyi ideig tart a belso fuggveny.
Mert ha sokaig tart, akkor kell async lib, vagy promise.

---
Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

"Miert nem teszed be a memcache.get -be? Sebessegben lassu?"

"Ha a belső callback-ben return-ölök, azzal a külső callback hogy fog visszatérni? :)"
"Sehogy. De nem is kell, mivel a belso utan mar nincs programlogika."

"...ergo én is a geten belülre tenném."

Aki szerint a get-be kéne tennem, tudna rá írni példát? :)
Kíváncsi vagyok, mert a külső callback-nek kellene visszatérnie ahhoz, hogy a szóban forgó lerenderelt view részlet visszajusson a template kezelőhöz.

> Aki szerint a get-be kéne tennem, tudna rá írni példát? :)

Fogod a github.com-ot, regisztralsz, felteszel egy tenyleg minimal projektet,
ahol a hiba elojon, es utana visszajosz, hogy probalkozzunk.

Vagy ugy kepzeled el, hogy felteszunk mi is egy handlebart,
egy node.js-t meg egy memcached-et, es utana megprobaljuk a te hibadat eloidezni?

Roviden: ugy csinald meg, hogyha itt nem jarsz sikerrel, akkor egy-az-egyben fel tud dobni a stackoverflow-ra.

Egyebkent ha mar offtopic, en a handlebar-t nem szeretem es semmi szerver oldali template-et.
Szerintem az a kliens dolga (max ejs ha minden kotel szakad).

---
Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

"Vagy ugy kepzeled el, hogy felteszunk mi is egy handlebart,
egy node.js-t meg egy memcached-et, es utana megprobaljuk a te hibadat eloidezni?"

Altalaban tamogatom ezt a stilust, de ebben az esetben a kerdezo eleg tisztan leirta a problemat, foleg ha a tobbi hsz-t is vegigolvasod. memcached.get() aszinkron, az eredmenyet a parameterul adott callback kapja meg, na azt kene a legkulso fuggveny eredmenyekent visszateriteni.

----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"
--> YouTube csatornám

"memcached.get() aszinkron, az eredmenyet a parameterul adott callback kapja meg, na azt kene a legkulso fuggveny eredmenyekent visszateriteni"

Pontosan így van.
Egyébként természetesen nem várom el senkitől, hogy előidézze a "hibát", a hozzászólásomban felfedezhető némi irónia, arra próbáltam rávilágítani, hogy ketten is magabiztosan kijelentették, hogy mi a megoldás, ami egyébként egyáltalán nem járható út (pont amiatt amit te is leírtál), de mivel ennyire magabiztosak, gondoltam egy pár soros kódban materializálni tudnák, hogy hogyan is nézne ez ki a gyakorlatban.


...
retVal = null;
async.waterfall([
 function(next) {
   memcached.get(cacheKey, next);
 }, function(data, next) {
    if (data) {
      next(null, data);
    } else {
      html = options.fn(context);
      memcached.set(cacheKey, html, 0, function (err) {next(err, data)});
    }
}], function (err, result) {
  retVal = result;
});
return new hbs.handlebars.SafeString(retVal);

> Altalaban tamogatom ezt a stilust, de ebben az esetben a kerdezo eleg tisztan leirta a problemat

Es irtunk 3 iranyvonalat:
1. belso fuggvenybol kell visszaterni
(ehhez kellene egy egyszeru peldaprogram, ha tovabbra se megy a kerdezonek,
hogy ki lehessen probalnunk a sajat hulyesegunket:)
2. async (es ezen belul a waterfall)
3. promise

Ennel tobbet pelda kod nelkul elvarni nem lehet.

De igazabol felolem mindenki ugy csinalja, ahogy gondolja.
Nekem e honapra a segito kreditem elfogyott, mostmar csak troll kreditem maradt. >:]

---
Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....