Skip to content

Commit e43bde0

Browse files
committed
DbUpgrader fixed
Don't generate PID file
1 parent 2a277be commit e43bde0

File tree

5 files changed

+93
-40
lines changed

5 files changed

+93
-40
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ dist
1616
/.settings
1717
node_modules
1818
front/package-lock.json
19-
*.log
19+
*.log
20+
filecache*

app/AppModule.scala

+33-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import java.io.IOException
12
import java.util.concurrent.Executors
23

34
import cats.effect.Effect
@@ -6,6 +7,7 @@ import com.google.inject.TypeLiteral
67
import com.typesafe.scalalogging.StrictLogging
78
import io.sentry.Sentry
89
import lib.App._
10+
import lib.AppException.MultipleFailuresException
911
import lib._
1012
import lib.db.{Dao, DbScheme, DbUpgrader}
1113
import lib.server.CloudConnector
@@ -26,6 +28,7 @@ import utils.AllowedWsApiOrigins
2628
import scala.collection.JavaConverters._
2729
import scala.concurrent.ExecutionContext
2830
import scala.concurrent.duration._
31+
import scala.util.control.NonFatal
2932

3033
class AppModule(environment: Environment, configuration: Configuration)
3134
extends ScalaModule
@@ -54,12 +57,13 @@ class AppModule(environment: Environment, configuration: Configuration)
5457

5558
DB.autoCommit { implicit session =>
5659
DbScheme.create
57-
DbUpgrader.upgrade
5860
}
5961

6062
override def configure(): Unit = {
6163
bindConfig(config.root(), "")(binder())
6264

65+
val rootMonitor = Monitor.noOp() // TODO
66+
6367
implicit val scheduler: Scheduler = Scheduler(
6468
executor = Executors.newScheduledThreadPool(4),
6569
ec = ExecutionContext.fromExecutorService(Executors.newCachedThreadPool())
@@ -70,15 +74,27 @@ class AppModule(environment: Environment, configuration: Configuration)
7074

7175
val blockingScheduler = Scheduler.io()
7276

73-
val rootMonitor = Monitor.noOp() // TODO
77+
val dao = new Dao(blockingScheduler)
78+
79+
// upgrade DB
80+
DB.autoCommit { implicit session =>
81+
val upgrader = new DbUpgrader(dao)
82+
upgrader.upgrade.value.runSyncUnsafe(30.seconds) match {
83+
case Right(_) => // ok
84+
case Left(err @ MultipleFailuresException(causes)) =>
85+
logger.error(s"Multiple failures while upgrading the DB:\n${causes.mkString("\n")}")
86+
throw err
87+
case Left(err) =>
88+
throw err
89+
}
90+
}
7491

7592
bind[AllowedWsApiOrigins].toInstance(AllowedWsApiOrigins(config.getStringList("allowedWsApiOrigins").asScala))
7693

7794
val deviceId = DeviceId(config.getString("deviceId"))
7895
bind[DeviceId].toInstance(deviceId)
7996

8097
val cloudConnector = CloudConnector.fromConfig(config.getConfig("cloudConnector"), blockingScheduler)
81-
val dao = new Dao(blockingScheduler)
8298
val settings = new Settings(dao)
8399
val stateManager = new StateManager(deviceId, cloudConnector, dao, settings)
84100

@@ -118,9 +134,20 @@ class AppModule(environment: Environment, configuration: Configuration)
118134

119135
// startup:
120136

121-
stateManager.appInit().value.toIO.unsafeRunSync() match {
122-
case Right(_) => settings.initializing(false)
123-
case Left(err) => throw err
137+
try {
138+
stateManager.appInit().value.runSyncUnsafe(5.minutes) match {
139+
case Right(_) => settings.initializing(false)
140+
case Left(err) => throw err
141+
}
142+
} catch {
143+
case e: IOException if e.getMessage.startsWith("Failed to connect") =>
144+
settings.session(None).value.runSyncUnsafe(2.seconds)
145+
logger.info("Could not initialize app because server is unavailable", e)
146+
settings.initializing(false)
147+
148+
case NonFatal(e) =>
149+
logger.error("Could not initialize app", e)
150+
throw e
124151
}
125152
}
126153

app/lib/db/DbScheme.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package lib.db
22

3-
import lib.App
3+
import lib.{App, AppVersion}
44
import scalikejdbc._
55

66
object DbScheme {
@@ -43,9 +43,11 @@ object DbScheme {
4343
|
4444
""".stripMargin.executeUpdate().apply()
4545

46-
sql"""
47-
|insert ignore into settings values ('db_version', ${currentVersionStr});
46+
if (App.version > AppVersion(0, 1, 3)) {
47+
sql"""
48+
|insert ignore into settings values ('db_version', ${currentVersionStr});
4849
""".stripMargin.executeUpdate().apply()
50+
}
4951
}
5052

5153
def truncateAll(implicit session: DBSession): Unit = {

app/lib/db/DbUpgrader.scala

+49-30
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,60 @@
11
package lib.db
22

3+
import cats.data.EitherT
34
import com.typesafe.scalalogging.StrictLogging
4-
import lib.AppVersion
5+
import lib.App._
6+
import lib.AppException.DbException
7+
import lib.db.DbUpgrader._
8+
import lib.{App, AppException, AppVersion}
9+
import monix.eval.Task
10+
import monix.execution.Scheduler
511
import scalikejdbc._
612

713
import scala.collection.immutable.TreeMap
814

9-
object DbUpgrader extends StrictLogging {
15+
class DbUpgrader(dao: Dao)(implicit sch: Scheduler) extends StrictLogging {
16+
17+
def upgrade(implicit session: DBSession): Result[Unit] = {
18+
dao
19+
.getSetting("db_version")
20+
.map(_.flatMap(AppVersion(_).toOption).getOrElse {
21+
logger.debug("Didn't found DB version, fallback to 0.1.3")
22+
AppVersion(0, 1, 3) // last version without this
23+
})
24+
.flatMap { currentVersion =>
25+
logger.debug(s"Current DB version: $currentVersion")
26+
27+
val upgrades = VersionsChanges.filterKeys(_ > currentVersion)
28+
29+
upgrades
30+
.map {
31+
case (targetVersion, query) =>
32+
val versionStr = targetVersion.toString
33+
App.leaveBreadcrumb("Upgrading DB", Map("version" -> versionStr))
34+
35+
logger.debug(s"Upgrading DB to version $versionStr")
36+
37+
EitherT {
38+
Task(query.apply())
39+
.map(_ => Right(()))
40+
.onErrorHandle { e =>
41+
Left(DbException(s"Error while upgrading the DB scheme to version $targetVersion", e): AppException)
42+
}
43+
}.flatMap { _ =>
44+
dao
45+
.setSetting("db_version", versionStr)
46+
.map(_ => logger.info(s"DB upgraded to version $versionStr"))
47+
}
48+
}
49+
.toList
50+
.sequentially
51+
.map(_ => ())
52+
}
53+
}
54+
}
55+
56+
object DbUpgrader {
1057
private final val VersionsChanges = TreeMap[AppVersion, SQLUpdate](
1158
AppVersion(0, 1, 4) -> sql""" alter table settings add constraint prim_key PRIMARY KEY (key)""".update()
1259
)
13-
14-
def upgrade(implicit session: DBSession): Unit = {
15-
val currentVersion: AppVersion = {
16-
sql""" select value from settings where key='db_version' """
17-
.single()
18-
.map(_.string("value"))
19-
.single()
20-
.apply
21-
.flatMap(AppVersion(_).toOption)
22-
.getOrElse {
23-
logger.warn("Didn't found DB version, fallback to 0.1.3")
24-
AppVersion(0, 1, 3) // last version without this
25-
}
26-
}
27-
28-
logger.debug(s"Current DB version: $currentVersion")
29-
30-
val upgrades = VersionsChanges.filterKeys(_ > currentVersion)
31-
32-
upgrades.foreach {
33-
case (version, query) =>
34-
logger.debug(s"Upgrading DB to version $version")
35-
query.apply()
36-
val versionStr = version.toString
37-
sql""" update settings set value=${versionStr} where key='db_version' """.update().apply()
38-
logger.debug(s"DB upraded to version $version")
39-
}
40-
}
4160
}

conf/reference.conf

+4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ play.filters {
3535
}
3636
}
3737

38+
play.server {
39+
pidfile.path = "/dev/null"
40+
}
41+
3842
play.http.secret.key = "%APPLICATION_SECRET%"
3943

4044
play.i18n.langs = ["cs"]

0 commit comments

Comments
 (0)