I've been trying to figure out how to use node-fibers to make my database code less messy in node.js, but I can't get it to work. I boiled the code down to this as a minimum test case:

var Future = require('fibers/future');
var pg=require('pg');

var connstr = "pg://not_the_real_user:or_password@localhost/db";
var pconnect = Future.wrap(pg.connect);

Fiber(function() {
    var client = pconnect(connstr).wait();
    console.log("called function");
}).run();

If I leave it as is, I get the following error:

pgfuture.js:10
}).run();
   ^
TypeError: undefined is not a function
    at Object.PG.connect.pools.(anonymous function).genericPool.Pool.create (/home/erik/code/treehouse-node/node_modules/pg/lib/index.js:49:20)
    at dispense (/home/erik/code/treehouse-node/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js:223:17)
    at Object.exports.Pool.me.acquire (/home/erik/code/treehouse-node/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js:267:5)
    at PG.connect (/home/erik/code/treehouse-node/node_modules/pg/lib/index.js:75:15)
    at Future.wrap (/home/erik/code/treehouse-node/node_modules/fibers/future.js:30:6)
    at /home/erik/code/treehouse-node/pgfuture.js:8:18

However, if I comment out the line that calls pconnect, I get the "called function" message on the console and no errors. The example on the github page has an almost identical structure, and it does work correctly on my system, but I'm stumped as to what I'm doing wrong here.

Edit: Additional details

I've managed to get the code to run after a fashion in two different ways that seem unrelated, but both have the same behavior. After the function finishes, node just hangs and I have to kill it with ctrl-c. Here are the two things I've done to get that result:

1) Wrap pg.connect in an anonymous function, and then wrap THAT with Future:

pconnect = Future.wrap(function(err,cb){pg.connect(err,cb);});

2) This one is a real mystery, but it appears to have the same result. Inside the fiber, I just directly call pg.connect before the call to pconnect, and everything seems to work out.

// add this line before call to pconnect
pg.connect(connstr, function(e,c){console.log("connected.");});
// and now the original call to pconnect
var client = pconnect(connstr).wait();

I can imagine a circumstance in which (1) would make sense if, for example, the pg.connect function has other optional arguments that are somehow interfering with the expected layout of the Future.wrap call. Another possibility is that an object is going out of scope and the "this" reference is undefined when the actual call to pconnect is made. I'm at a loss to understand why (2) has any effect though.

Edit: partial answer

Okay, so I answered at least part of the question. The thought I had about object scope turned out to be correct, and by using the bind() function I was able to eliminate the extra layer of callback wrapping:

var pconnect = Future.wrap(pg.connect.bind(pg));

It still hangs at the end of the execution for unknown reasons though.

有帮助吗?

解决方案

Are you disconnecting from database at the end of execution?

If not, it prevents node.js program from exiting.

其他提示

Adding another code of my own which leaks.

@Almad I'm disconnecting here with the provided callback, but still hangs:

var future = Future.task(function() {
   var ret = Future.wrap (pg.connect.bind(pg), "array") (conString).wait ();
   ret[1]();
}).detach();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top