Skip to content
This repository was archived by the owner on Nov 18, 2024. It is now read-only.

Commit 6b5e9e4

Browse files
authored
Merge pull request #67 from hmrc/BDOG-144-allow-configuring-mongo-timeout
BDOG-114 make it possible to configure the default 10s timeout
2 parents c0d966f + 35005a3 commit 6b5e9e4

File tree

7 files changed

+51
-20
lines changed

7 files changed

+51
-20
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,15 @@ class SimpleTestRepository @Inject()(mongoComponent: ReactiveMongoComponent)
164164

165165
Formats for BSONObjectId and Joda time classes are implemented (see [ReactiveMongoFormats](https://github.com/hmrc/simple-reactivemongo/blob/master/src/main/scala/uk/gov/hmrc/mongo/ReactiveMongoFormats.scala))
166166

167+
#### Configuration Options
168+
169+
There is a default timeout of 10 seconds when making connections with Mongo. This value is
170+
configurable by setting the key:
171+
172+
`mongodb.dbTimeoutMsecs=10000`
173+
174+
Within your application.conf
175+
167176
#### Configure underlying Akka system
168177

169178
ReactiveMongo loads it's configuration from the key `mongo-async-driver`

project/LibraryDependencies.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@ object LibraryDependencies {
1111
"org.reactivemongo" %% "reactivemongo" % "0.16.1"
1212
),
1313
play25 = Seq(
14-
"org.slf4j" % "slf4j-api" % "1.7.21",
15-
"org.slf4j" % "log4j-over-slf4j" % "1.7.21",
14+
"org.slf4j" % "slf4j-api" % "1.7.26",
15+
"org.slf4j" % "log4j-over-slf4j" % "1.7.26",
1616
"com.typesafe.play" %% "play" % play25Version,
1717
"org.reactivemongo" %% "reactivemongo-play-json" % "0.16.0-play25",
1818
// force dependencies due to security flaws found in jackson-databind < 2.9.x using XRay
19-
"com.fasterxml.jackson.core" % "jackson-core" % "2.9.7",
20-
"com.fasterxml.jackson.core" % "jackson-databind" % "2.9.7",
21-
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.9.7",
22-
"com.fasterxml.jackson.datatype" % "jackson-datatype-jdk8" % "2.9.7",
23-
"com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.9.7",
19+
"com.fasterxml.jackson.core" % "jackson-core" % "2.9.8",
20+
"com.fasterxml.jackson.core" % "jackson-databind" % "2.9.8",
21+
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.9.8",
22+
"com.fasterxml.jackson.datatype" % "jackson-datatype-jdk8" % "2.9.8",
23+
"com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.9.8",
2424
// force dependencies due to security flaws found in xercesImpl 2.11.0
2525
"xerces" % "xercesImpl" % "2.12.0"
2626
),
2727
play26 = Seq(
28-
"org.slf4j" % "slf4j-api" % "1.7.25",
29-
"org.slf4j" % "log4j-over-slf4j" % "1.7.25",
28+
"org.slf4j" % "slf4j-api" % "1.7.26",
29+
"org.slf4j" % "log4j-over-slf4j" % "1.7.26",
3030
"com.typesafe.play" %% "play" % play26Version,
3131
"com.typesafe.play" %% "play-guice" % play26Version,
3232
"org.reactivemongo" %% "reactivemongo-play-json" % "0.16.0-play26"
@@ -37,9 +37,9 @@ object LibraryDependencies {
3737
shared = Seq(
3838
"com.outworkers" %% "util-samplers" % "0.40.0" % Test,
3939
"org.pegdown" % "pegdown" % "1.6.0" % Test,
40-
"org.scalacheck" %% "scalacheck" % "1.13.4" % Test,
40+
"org.scalacheck" %% "scalacheck" % "1.13.5" % Test,
4141
"org.scalamock" %% "scalamock" % "4.1.0" % Test,
42-
"org.scalatest" %% "scalatest" % "3.0.5" % Test,
42+
"org.scalatest" %% "scalatest" % "3.0.6" % Test,
4343
"ch.qos.logback" % "logback-classic" % "1.2.3" % Test
4444
),
4545
play25 = Seq(

src/main/scala/play/modules/reactivemongo/MongoConfig.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class MongoConfig(
5858
case _ => None
5959
}
6060

61+
lazy val dbTimeout: Option[FiniteDuration] =
62+
mongoConfig.getOptional[Long]("dbTimeoutMsecs")
63+
.map(dbTimeout => new FiniteDuration(dbTimeout, TimeUnit.MILLISECONDS))
64+
6165
private lazy val mongoConfig: Configuration = configuration
6266
.getOptional[Configuration]("mongodb")
6367
.orElse(configuration.getOptional[Configuration](s"${environment.mode}.mongodb"))

src/main/scala/play/modules/reactivemongo/ReactiveMongoHmrcModule.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,12 @@ class ReactiveMongoComponentImpl @Inject()(
5252

5353
lazy val mongoConnector: MongoConnector = MongoConnector(
5454
mongoConfig.uri,
55-
mongoConfig.maybeFailoverStrategy
55+
mongoConfig.maybeFailoverStrategy,
56+
mongoConfig.dbTimeout
5657
)
5758

59+
Logger.debug(s"ReactiveMongoPlugin: MongoConnector configuration being used: $mongoConnector")
60+
5861
lifecycle.addStopHook { () =>
5962
Future.successful {
6063
Logger.info("ReactiveMongoPlugin stops, closing connections...")

src/main/scala/reactivemongo/ReactiveMongoHelper.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ import reactivemongo.core.nodeset.Authenticate
2121
import scala.concurrent.{Await, ExecutionContext, Future}
2222
import reactivemongo.api._
2323

24+
import scala.concurrent.duration._
2425
import scala.language.postfixOps
2526

2627
object ReactiveMongoHelper {
2728

29+
val DEFAULT_DB_TIMEOUT = 10 seconds
30+
2831
@deprecated(message = "Use case class constructor that takes MongoConnectionOptions", "7.0.0")
2932
def apply(
3033
dbName: String,
@@ -46,7 +49,8 @@ case class ReactiveMongoHelper(
4649
servers: Seq[String],
4750
auth: Seq[Authenticate],
4851
failoverStrategy: Option[FailoverStrategy],
49-
connectionOptions: MongoConnectionOptions = MongoConnectionOptions()) {
52+
connectionOptions: MongoConnectionOptions = MongoConnectionOptions(),
53+
dbTimeout: Option[FiniteDuration] = None) {
5054

5155
implicit val ec: ExecutionContext = ExecutionContext.Implicits.global
5256
lazy val driver = new MongoDriver
@@ -57,9 +61,8 @@ case class ReactiveMongoHelper(
5761
options = connectionOptions
5862
)
5963

60-
import scala.concurrent.duration._
6164
lazy val db: DefaultDB = failoverStrategy match {
62-
case Some(fs: FailoverStrategy) => Await.result(connection.database(dbName, fs), 10 seconds)
63-
case None => Await.result(connection.database(dbName), 10 seconds)
65+
case Some(fs: FailoverStrategy) => Await.result(connection.database(dbName, fs), dbTimeout.getOrElse(ReactiveMongoHelper.DEFAULT_DB_TIMEOUT))
66+
case None => Await.result(connection.database(dbName), dbTimeout.getOrElse(ReactiveMongoHelper.DEFAULT_DB_TIMEOUT))
6467
}
6568
}

src/main/scala/uk/gov/hmrc/mongo/SimpleMongoConnection.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package uk.gov.hmrc.mongo
1818

1919
import reactivemongo.api.FailoverStrategy
2020

21+
import scala.concurrent.duration.FiniteDuration
2122
import scala.language.postfixOps
2223

2324
trait SimpleMongoConnection {
@@ -30,6 +31,7 @@ trait SimpleMongoConnection {
3031

3132
val mongoConnectionUri: String
3233
val failoverStrategy: Option[FailoverStrategy]
34+
val dbTimeout: Option[FiniteDuration]
3335

3436
implicit def db: () => DefaultDB = () => mongoDb
3537

@@ -39,18 +41,18 @@ trait SimpleMongoConnection {
3941

4042
lazy val helper: ReactiveMongoHelper = MongoConnection.parseURI(mongoConnectionUri) match {
4143
case Success(MongoConnection.ParsedURI(hosts, options, ignoreOptions, Some(db), auth)) =>
42-
ReactiveMongoHelper(db, hosts.map(h => h._1 + ":" + h._2), auth.toList, failoverStrategy, options)
44+
ReactiveMongoHelper(db, hosts.map(h => h._1 + ":" + h._2), auth.toList, failoverStrategy, options, dbTimeout)
4345
case Success(MongoConnection.ParsedURI(_, _, _, None, _)) =>
4446
throw new Exception(s"Missing database name in mongodb.uri '$mongoConnectionUri'")
4547
case Failure(e) => throw new Exception(s"Invalid mongodb.uri '$mongoConnectionUri'", e)
4648
}
4749

4850
def close() {
49-
val f = helper.connection.askClose()(10 seconds)
50-
Await.ready(f, 10 seconds)
51+
val f = helper.connection.askClose()(dbTimeout.getOrElse(ReactiveMongoHelper.DEFAULT_DB_TIMEOUT))
52+
Await.ready(f, dbTimeout.getOrElse(ReactiveMongoHelper.DEFAULT_DB_TIMEOUT))
5153
}
5254

5355
}
5456

55-
case class MongoConnector(mongoConnectionUri: String, failoverStrategy: Option[FailoverStrategy] = None)
57+
case class MongoConnector(mongoConnectionUri: String, failoverStrategy: Option[FailoverStrategy] = None, dbTimeout: Option[FiniteDuration] = None)
5658
extends SimpleMongoConnection

src/test/scala/play/modules/reactivemongo/MongoConfigSpec.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ class MongoConfigSpec extends WordSpec with MockFactory with PropertyChecks {
9999
s"return None for 'maybeFailoverStrategy' if '$mongodbConfigKey.failoverStrategy' not present in config" in new Setup {
100100
mongoConfig(mongodbConfigKey -> Map.empty).maybeFailoverStrategy shouldBe None
101101
}
102+
103+
s"return None for 'dbTimeoutMsecs' if '$mongodbConfigKey.dbTimeoutMsecs' not present in config" in new Setup {
104+
mongoConfig(mongodbConfigKey -> Map.empty).dbTimeout shouldBe None
105+
}
106+
107+
s"override 'dbTimeoutMsecs' if specified under '$mongodbConfigKey.dbTimeoutMsecs'" in new Setup {
108+
val dbTimeout = mongoConfig(s"$mongodbConfigKey.dbTimeoutMsecs" -> dbTimeoutMsecs).dbTimeout
109+
dbTimeout shouldBe Some(new FiniteDuration(dbTimeoutMsecs, MILLISECONDS))
110+
}
102111
}
103112
}
104113

@@ -108,6 +117,7 @@ class MongoConfigSpec extends WordSpec with MockFactory with PropertyChecks {
108117
val uri = "mongouri"
109118
val channels = 1
110119
val initialDelayMsecs = 1234
120+
val dbTimeoutMsecs = 1234
111121
val retries = 5
112122

113123
def mongoConfig(configEntries: (String, Any)*): MongoConfig =

0 commit comments

Comments
 (0)