You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by James Dingwall <ja...@zynstra.com> on 2013/12/12 14:54:08 UTC

Update functions and require()

Hi,

I am experiencing some problems with update functions which I use to 
create documents in CouchDB when they are using require() to load a 
common library.  It seems that after publishing the design document then 
the first update function to be called works well but any subsequent 
ones do not call require().  With the log() call in the require I see 
this appear in the call to the first update but it does not appear with 
any others, they print a stack trace such as:
[Thu, 12 Dec 2013 13:20:55 GMT] [error] [<0.6458.0>] httpd 500 error 
response:
  {"error":"render_error","reason":"function raised error: (new 
ReferenceError(\"docUtil is not defined\", \"updates.template\", 54))
stacktrace: (null,[object Object])@updates.template:54
runUpdate(<<<body of update function>>>),[object Object],[object 
Array])@/usr/local/share/couchdb/server/main.js:1033
(\"_design/provision\",[object Array],[object 
Array])@/usr/local/share/couchdb/server/main.js:1517
()@/usr/local/share/couchdb/server/main.js:1562
@/usr/local/share/couchdb/server/main.js:1573
"}

As far as I can tell by require()d code is ok since the same structure 
is working for other things.  What it seems to me is that it is loaded 
by CouchDB for the first update function and is then recorded as loaded 
but a second update function needing the same code has its require 
ignored but cannot reference the in memory copy produce by the require 
from the first update.

I have tested versions CouchDB 1.3.1, 1.4.0 and 1.5.0 all with the same 
behaviour.  I am running on Ubuntu precise with esl-erlang 1:16.b.3-1.

Any suggestions on where to look next?

Thanks,
James


As an example:

The updates are all of the form:
function(doc, req) {
   require('views/lib/docUtil');

   if(!doc) {
      doc = {some: defaults}
   }

   // some other code

   doc.meta = docUtil.metaCreate(req);

   return([doc, JSON.stringify(doc, undefined, 2)]);
}

views/lin/docUtil is similar too:
(function(global) {

var _metaCreate = function(req) {
...
};

var _metaModify = function(req) {
...
};

log('docUtil loaded')
global.docUtil = {
   metaCreate = _metaCreate,
   metaModify = metaModify
};

})(exports.docUtil = this)


Re: Update functions and require()

Posted by James Dingwall <ja...@zynstra.com>.
James Dingwall wrote:
> James Dingwall wrote:
>> Hi,
>>
>> I am experiencing some problems with update functions which I use to 
>> create documents in CouchDB when they are using require() to load a 
>> common library.  It seems that after publishing the design document 
>> then the first update function to be called works well but any 
>> subsequent ones do not call require().  With the log() call in the 
>> require I see this appear in the call to the first update but it does 
>> not appear with any others, they print a stack trace such as:
>> [Thu, 12 Dec 2013 13:20:55 GMT] [error] [<0.6458.0>] httpd 500 error 
>> response:
>>  {"error":"render_error","reason":"function raised error: (new 
>> ReferenceError(\"docUtil is not defined\", \"updates.template\", 54))
>> stacktrace: (null,[object Object])@updates.template:54
>> runUpdate(<<<body of update function>>>),[object Object],[object 
>> Array])@/usr/local/share/couchdb/server/main.js:1033
>> (\"_design/provision\",[object Array],[object 
>> Array])@/usr/local/share/couchdb/server/main.js:1517
>> ()@/usr/local/share/couchdb/server/main.js:1562
>> @/usr/local/share/couchdb/server/main.js:1573
>> "}
>>
>> As far as I can tell by require()d code is ok since the same 
>> structure is working for other things.  What it seems to me is that 
>> it is loaded by CouchDB for the first update function and is then 
>> recorded as loaded but a second update function needing the same code 
>> has its require ignored but cannot reference the in memory copy 
>> produce by the require from the first update.
>>
>> I have tested versions CouchDB 1.3.1, 1.4.0 and 1.5.0 all with the 
>> same behaviour.  I am running on Ubuntu precise with esl-erlang 
>> 1:16.b.3-1.
>>
>> Any suggestions on where to look next?
>>
>> Thanks,
>> James
>>
>>
>> As an example:
>>
>> The updates are all of the form:
>> function(doc, req) {
>>   require('views/lib/docUtil');
>>
>>   if(!doc) {
>>      doc = {some: defaults}
>>   }
>>
>>   // some other code
>>
>>   doc.meta = docUtil.metaCreate(req);
>>
>>   return([doc, JSON.stringify(doc, undefined, 2)]);
>> }
>>
>> views/lin/docUtil is similar too:
>> (function(global) {
>>
>> var _metaCreate = function(req) {
>> ...
>> };
>>
>> var _metaModify = function(req) {
>> ...
>> };
>>
>> log('docUtil loaded')
>> global.docUtil = {
>>   metaCreate = _metaCreate,
>>   metaModify = metaModify
>> };
>>
>> })(exports.docUtil = this)
>>
>
> Here is a complete test case design document which demonstrates the 
> problem.
>
> {
>    "_id": "_design/ptest",
>    "updates": {
>        "two": "function(doc, req) 
> {\n\trequire('views/lib/docUtil');\n\n\tif(!doc) {\n\t\tdoc = 
> {};\n\t}\n\n\tdoc._id = 'two';\n\n\tdoc.meta = 
> docUtil.metaCreate();\n\n\treturn([doc, JSON.stringify(doc, undefined, 
> 2)]);\n}",
>        "one": "function(doc, req) 
> {\n\trequire('views/lib/docUtil');\n\n\tif(!doc) {\n\t\tdoc = 
> {};\n\t}\n\n\tdoc._id = 'one';\n\n\tdoc.meta = 
> docUtil.metaCreate();\n\n\treturn([doc, JSON.stringify(doc, undefined, 
> 2)]);\n}"
>    },
>    "language": "javascript",
>    "views": {
>        "lib": {
>            "docUtil": "(function(global) {\n\nvar _metaCreate = 
> function() {\n\treturn({\n\t\ta: 'create',\n\t\tb: 
> 'bbbb'\n\t});\n};\n\nvar _metaModify = function() 
> {\n\treturn({\n\t\ta: 'modify',\n\t\tb: 
> 'bbbb'\n\t});\n};\n\nglobal.docUtil = {\n\tmetaCreate: 
> _metaCreate,\n\tmetaModify: _metaModify\n};\n\nlog('require 
> docUtil');\n\n})(exports.docUtil = this)"
>        }
>    },
>    "type": "design/ptest"
> }
>
> Call the update functions like:
> curl -X POST http://couchdb:5984/zydev/_design/ptest/_update/one - 
> creates a document
> curl -X POST http://couchdb:5984/zydev/_design/ptest/_update/two - fails
I have opened https://issues.apache.org/jira/browse/COUCHDB-1961 for 
this issue as it appears to be a bug in the couchdb query server module 
cache.

James

Re: Update functions and require()

Posted by James Dingwall <ja...@zynstra.com>.
James Dingwall wrote:
> Hi,
>
> I am experiencing some problems with update functions which I use to 
> create documents in CouchDB when they are using require() to load a 
> common library.  It seems that after publishing the design document 
> then the first update function to be called works well but any 
> subsequent ones do not call require().  With the log() call in the 
> require I see this appear in the call to the first update but it does 
> not appear with any others, they print a stack trace such as:
> [Thu, 12 Dec 2013 13:20:55 GMT] [error] [<0.6458.0>] httpd 500 error 
> response:
>  {"error":"render_error","reason":"function raised error: (new 
> ReferenceError(\"docUtil is not defined\", \"updates.template\", 54))
> stacktrace: (null,[object Object])@updates.template:54
> runUpdate(<<<body of update function>>>),[object Object],[object 
> Array])@/usr/local/share/couchdb/server/main.js:1033
> (\"_design/provision\",[object Array],[object 
> Array])@/usr/local/share/couchdb/server/main.js:1517
> ()@/usr/local/share/couchdb/server/main.js:1562
> @/usr/local/share/couchdb/server/main.js:1573
> "}
>
> As far as I can tell by require()d code is ok since the same structure 
> is working for other things.  What it seems to me is that it is loaded 
> by CouchDB for the first update function and is then recorded as 
> loaded but a second update function needing the same code has its 
> require ignored but cannot reference the in memory copy produce by the 
> require from the first update.
>
> I have tested versions CouchDB 1.3.1, 1.4.0 and 1.5.0 all with the 
> same behaviour.  I am running on Ubuntu precise with esl-erlang 
> 1:16.b.3-1.
>
> Any suggestions on where to look next?
>
> Thanks,
> James
>
>
> As an example:
>
> The updates are all of the form:
> function(doc, req) {
>   require('views/lib/docUtil');
>
>   if(!doc) {
>      doc = {some: defaults}
>   }
>
>   // some other code
>
>   doc.meta = docUtil.metaCreate(req);
>
>   return([doc, JSON.stringify(doc, undefined, 2)]);
> }
>
> views/lin/docUtil is similar too:
> (function(global) {
>
> var _metaCreate = function(req) {
> ...
> };
>
> var _metaModify = function(req) {
> ...
> };
>
> log('docUtil loaded')
> global.docUtil = {
>   metaCreate = _metaCreate,
>   metaModify = metaModify
> };
>
> })(exports.docUtil = this)
>

Here is a complete test case design document which demonstrates the problem.

{
    "_id": "_design/ptest",
    "updates": {
        "two": "function(doc, req) 
{\n\trequire('views/lib/docUtil');\n\n\tif(!doc) {\n\t\tdoc = 
{};\n\t}\n\n\tdoc._id = 'two';\n\n\tdoc.meta = 
docUtil.metaCreate();\n\n\treturn([doc, JSON.stringify(doc, undefined, 
2)]);\n}",
        "one": "function(doc, req) 
{\n\trequire('views/lib/docUtil');\n\n\tif(!doc) {\n\t\tdoc = 
{};\n\t}\n\n\tdoc._id = 'one';\n\n\tdoc.meta = 
docUtil.metaCreate();\n\n\treturn([doc, JSON.stringify(doc, undefined, 
2)]);\n}"
    },
    "language": "javascript",
    "views": {
        "lib": {
            "docUtil": "(function(global) {\n\nvar _metaCreate = 
function() {\n\treturn({\n\t\ta: 'create',\n\t\tb: 
'bbbb'\n\t});\n};\n\nvar _metaModify = function() {\n\treturn({\n\t\ta: 
'modify',\n\t\tb: 'bbbb'\n\t});\n};\n\nglobal.docUtil = {\n\tmetaCreate: 
_metaCreate,\n\tmetaModify: _metaModify\n};\n\nlog('require 
docUtil');\n\n})(exports.docUtil = this)"
        }
    },
    "type": "design/ptest"
}

Call the update functions like:
curl -X POST http://couchdb:5984/zydev/_design/ptest/_update/one - 
creates a document
curl -X POST http://couchdb:5984/zydev/_design/ptest/_update/two - fails