What should be the lifecycle of afMongo's MongoClient?

97 views Asked by At

Based on the afMongo example I'm currently doing this:

mongoClient := MongoClient(ActorPool(), `mongodb://localhost:27017`)
collection  := mongoClient.db("mydb").collection("mycollection")
...
// inserts or queries here
...
mongoClient.shutdown

My understanding is that MongoClient uses a pooled connection. If that's correct then I believe I can share the MongoClient across all my DAOs and only shutting it down when the afBedSheet application is shut down.

  1. Is this assumption correct?
  2. How can I hook the MongoClient shutdown to the afBedSheet shutdown, please?
1

There are 1 answers

3
Steve Eynon On BEST ANSWER
  1. Yes. You only need one MongoClient.
  2. Use the RegistryShutdown service. When BedSheet shutsdown, it also shutsdowns the IoC registry.

I would have the ConnectionManager as a service, and shut that down. So in your AppModule:

@Build
static ConnectionManager buildConnectionManager() {
    ConnectionManagerPooled(ActorPool(), `mongodb://localhost:27017`)
}

@Contribute { serviceType=RegistryShutdown# }
static Void contributeRegistryShutdown(Configuration config, ConnectionManager conMgr) {
    config.add(|->| { conMgr.shutdown } )
}

MongoClient could also be a service.

You could also rewrite the above to be a little more, um, correct. I tend to use the ActorPools service to keep tabs on them.

static Void bind(ServiceBinder binder) {
    binder.bind(MongoClient#)
}

@Build { serviceId="afMongo::ConnectionManager" }
static ConnectionManager buildConnectionManager(ConfigSource configSrc, ActorPools actorPools) {
    actorPool := actorPools.get("myPod.connectionManager")
    return ConnectionManagerPooled(actorPool , `mongodb://localhost:27017`)
}

@Contribute { serviceType=ActorPools# }
static Void contributeActorPools(Configuration config) {
    config["myPod.connectionManager"] = ActorPool() { it.name = "myPod.connectionManager"; it.maxThreads = 1 }
}

@Contribute { serviceType=RegistryShutdown# }
static Void contributeRegistryShutdown(Configuration config, ConnectionManager conMgr) {
    config["myPod.closeConnections"] = |->| {
        conMgr.shutdown
    }
}

myPod.closeConnections is just an arbitrary name and in the example it is not used anywhere else.`

But you could use it to override or remove the contribution. Some future test scenario could add a MyTestAppModule with the following:

@Contribute { serviceType=RegistryShutdown# }
static Void contributeRegistryShutdown(Configuration config) {
    config.remove("myPod.closeConnections")
}

Probably not useful in this particular instance, but useful to know about.