Ermouth,
Congratulations with digging out hidden features of CouchDB!
I presume this works with new 2.0 and 1.7 and that these versions now have a 
new feature, Caching:)
johs

> On 26. mai 2016, at 22.17, ermouth <ermo...@gmail.com> wrote:
> 
> Tested approach, works like a charm )
> 
> Surprisingly, it appears that approach is more suitable not for rendering
> pages, but for requests view->list, that respond with hundreds or thousands
> of small rows. In those cases I observe sometimes 2 orders of magnitude
> gain or even more, ie 300-500ms query server exec time turns into 3-5ms.
> 
> Even adding net latencies, that are around 100ms, gain is significant.
> 
> For page render, net latencies dim the gain, cause there is no visible
> difference between 100 and 150 ms lag at client side.
> 
> ermouth
> 
> 2016-05-19 11:41 GMT+03:00 ermouth <ermo...@gmail.com>:
> 
>>> - a function in a _list of a certain ddoc called directly via the _list
>> endpint
>> 
>> It‘s called via rewrite. Rewrite decides to call list. If rewrite already
>> have a result in cache and the result is not too old, rewrite sends results
>> directly.
>> 
>> If there is no result cached or it‘s too old, rewrite redirects to list.
>> And list, in turn, not only sends result, but caches it as well.
>> 
>>> - could you give us som sinppets
>> 
>> You make branch in ddoc, say .Cache, with code like:
>> 
>> (function(){
>> var cache = {};
>> exports.Cache = {
>>  get: function (key) {return cache[key]},
>>  put: function (key, val) {cache[key] = val;}
>> }
>> })();
>> 
>> In both rewrite and list to access cache you just use
>> 
>> var Cache = require ('Cache').Cache;
>> 
>> Now you can use it like Cache.get(key) and Cache.put(key, val) in rewrite
>> and list. Your cache will persist between requests until you change ddoc or
>> SM crashes.
>> 
>> 
>> ermouth
>> 
>> 2016-05-19 7:42 GMT+03:00 Johs Ensby <j...@b2w.com>:
>> 
>>> Hi Ermouth,
>>> this sounds like a bonus feature of significant value:)
>>> Together with the rewrite function this discovery would keep the couchapp
>>> enthusiasts of the community happy for a looong time, I believe.
>>> 
>>> If I understand you right,
>>> - a function in a _list of a certain ddoc called directly via the _list
>>> endpint (NOT via  _rewrite)
>>> - can cache a rendered result (e.g. a html page)
>>> - for a subsequent request via _rewrite (of the same ddoc) to pick up the
>>> cached result from RAM
>>> - using a timestamp inside that _rewrite function to compare against the
>>> timestamped name of the cached result to validate that the age is within a
>>> chosen tolerance
>>> 
>>> Following this 2-step approach (_list, then _rewrite)..
>>> - the _list function would have the full request context
>>> - while the _rewrite would have the limited request object available
>>> - the _rewrite and _list endpoints would need to be available
>>> 
>>> Control questions
>>> - does this mean that you cannot point a vhost to _rewrite and run all
>>> calls to _list via rewrite functions?
>>> - if you have one vhost pointing to _rewrite of a ddoc and another to
>>> e.g. _list would they still share the cache?
>>> 
>>> Testing this
>>> - could you give us som sinppets on how to test this, I would love to see
>>> this in action and test it towards my JS rewrite functions.
>>> 
>>> br
>>> johs
>>> 
>>> 
>>>> On 19. mai 2016, at 00.01, ermouth <ermo...@gmail.com> wrote:
>>>> 
>>>> Since JS rewrites landed in 2.0, and I use JS rewrites heavily, I
>>> discover
>>>> some tricks with the new feature time to time. Despite I use patched
>>> 1.6.1
>>>> with js rewrites, tricks are suitable for at least single node 2.0 as
>>> well.
>>>> 
>>>> JS rewrites function runs in the context of a query server instance. QS
>>>> instance is a Spidermonkey process with 64Mb of RAM by default. It‘s
>>> single
>>>> threaded.
>>>> 
>>>> Actually, seems that all query server functions of one particular design
>>>> doc are executed inside one dedicated Spidermonkey instance. It means
>>> they
>>>> all share global context (also it means they share one thread).
>>>> 
>>>> Ddoc global context persists until Spidermonkey process is restarted. It
>>>> happens when SM instance crashes (runs out of RAM quota, unrecoverable
>>>> error happens etc), or when underlying design doc is changed.
>>>> 
>>>> It means _list function can cache results of rendering into RAM, and
>>>> _rewrite function can later quickly respond with cached version,
>>> skipping
>>>> redirect to heavy map/list. Cache container is just JS closure,
>>>> instantiated/accessed using built-in require().
>>>> 
>>>> Unlike _list, JS rewrite function does not receive req.info, it would
>>> be
>>>> too slow to tap DB on each request. It means we can not invalidate
>>> cache on
>>>> local sequence change (DB update) – rewrite function just does not know
>>> DB
>>>> was updated.
>>>> 
>>>> However we can use timestamp-based caching, even several seconds TTL of
>>>> cache entries is enough to reduce average response time significantly
>>> (say,
>>>> order of magnitude).
>>>> 
>>>> I‘ve tested approach a little and found it very promising.
>>>> 
>>>> Since this dirty hack is possible with _list fns only, without js
>>> rewrites,
>>>> may be someone already employs it? Or at least tried?
>>>> 
>>>> ermouth
>>> 
>>> 
>> 

Reply via email to