The fastest and best way to do this is to use a module explicitly designed
for plugin architectures, like http://github.com/c9/architect or
http://github.com/flatiron/broadway. You can write your data access layers
as plugins and use dependency injection to set up the whole application,
passing in the database connection as necessary. The best thing about this
approach is that it helps keep the various pieces of your app loosely
coupled and makes the abstraction boundaries within the app clear.

If you find yourself trying to use global state, either via explicitly
global variables or by parking database connection handles in a module,
you're trying to force a solution and should probably take a step back and
think up a more naturally asynchronous strategy.

F

On Thu, Dec 6, 2012 at 4:36 PM, Jeremy Echols <[email protected]> wrote:

> We have an express app, and it's using a mongo database for various
> configuration details.  The app itself can have any number of plugins, and
> in some cases a plugin needs its configuration immediately upon load.
>  Plugins need to be loaded pretty early on so that they can theoretically
> hook into and/or override core functionality.
>
> In our current app, the database is loaded inside a "db manager" module.
>  When that module is loaded, it immediately creates a new connection to a
> mongo database.  After that, plugins are loaded and initialized.  Then our
> app's main code is run: setting up handlers for various routes, setting up
> nowjs handlers, etc.
>
> Previously, this worked fine.  Now that we're trying to set up plugins
> from the persistent database, though, it's all broken.  Many of you
> probably already realize what's going on: the db open() method is, of
> course, asynchronous.  This means the query to pull plugin configuration is
> relying on a connection that hasn't yet been established.
>
> I'm not sure why it silently fails when I do a find() call - I would have
> expected it to tell me the DB isn't ready or something - but that is beside
> the point.  We need to figure out a better approach so that plugins can get
> their DB configuration properly.
>
> So I see a few approaches and I'm wondering if we're going about this all
> wrong.
>
> *One*: in Rails and other frameworks I've used, there's generally a
> single DB connection that all queries go through.  I'm used to having a way
> to just grab the top-level DB object rather than having to open and close a
> DB connection every time I make a query.  But in node, making this kind of
> thing happen (and making sure the DB exists prior to the app running) feels
> really awkward to me.  I end up having to do something like this:
>
> db.open(..., function(err, obj)) {
>   # All app code goes here
> }
>
> This just feels wrong to me, having all the app's logic essentially in a
> function, but maybe that's a typical best practice, I have no idea.
>
> *Two*: another option would be to just open and close DB connections
> everywhere we need them, so that we don't have this concept of an app-wide
> DB instance.  To me, this feels backwards for a long-running app, but again
> I really don't know what is considered a best practice for a node
> application.  Socket overhead isn't going to be huge, so maybe that's the
> right way to tackle this situation so that we always know the DB will be
> there when we need it.  For instance:
>
> # App code stuff
>
> db.open(..., function(err, obj)) {
>   # Do some small db operation
>   obj.close();
> }
>
> # More app code stuff
>
> db.open(..., function(err, obj)) {
>   # Do some other small db operation
>   obj.close();
> }
>
> *Three*: another alternative would be to mix the two patterns - start up
> a DB instance that lives for the duration of the app, and use that for
> anything that's a user-driven event, such as a page request.  That is to
> say, only use the app-wide DB in cases where it's safe to assume the DB has
> had time to load.  Then for any DB hits which must happen at the absolute
> beginning of the application (when we can't even be sure 100ms have passed
> since the db.open() call was made), we open and close a separate DB handle.
>
> There are probably other options, but these three are all I've come up
> with so far.  Is there an established best practice?  If not, what would
> others doing similar things recommend?
>
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en
>

-- 
Job Board: http://jobs.nodejs.org/
Posting guidelines: 
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to