1
+ import java .io .IOException
1
2
import java .util .concurrent .Executors
2
3
3
4
import cats .effect .Effect
@@ -6,6 +7,7 @@ import com.google.inject.TypeLiteral
6
7
import com .typesafe .scalalogging .StrictLogging
7
8
import io .sentry .Sentry
8
9
import lib .App ._
10
+ import lib .AppException .MultipleFailuresException
9
11
import lib ._
10
12
import lib .db .{Dao , DbScheme , DbUpgrader }
11
13
import lib .server .CloudConnector
@@ -26,6 +28,7 @@ import utils.AllowedWsApiOrigins
26
28
import scala .collection .JavaConverters ._
27
29
import scala .concurrent .ExecutionContext
28
30
import scala .concurrent .duration ._
31
+ import scala .util .control .NonFatal
29
32
30
33
class AppModule (environment : Environment , configuration : Configuration )
31
34
extends ScalaModule
@@ -54,12 +57,13 @@ class AppModule(environment: Environment, configuration: Configuration)
54
57
55
58
DB .autoCommit { implicit session =>
56
59
DbScheme .create
57
- DbUpgrader .upgrade
58
60
}
59
61
60
62
override def configure (): Unit = {
61
63
bindConfig(config.root(), " " )(binder())
62
64
65
+ val rootMonitor = Monitor .noOp() // TODO
66
+
63
67
implicit val scheduler : Scheduler = Scheduler (
64
68
executor = Executors .newScheduledThreadPool(4 ),
65
69
ec = ExecutionContext .fromExecutorService(Executors .newCachedThreadPool())
@@ -70,15 +74,27 @@ class AppModule(environment: Environment, configuration: Configuration)
70
74
71
75
val blockingScheduler = Scheduler .io()
72
76
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
+ }
74
91
75
92
bind[AllowedWsApiOrigins ].toInstance(AllowedWsApiOrigins (config.getStringList(" allowedWsApiOrigins" ).asScala))
76
93
77
94
val deviceId = DeviceId (config.getString(" deviceId" ))
78
95
bind[DeviceId ].toInstance(deviceId)
79
96
80
97
val cloudConnector = CloudConnector .fromConfig(config.getConfig(" cloudConnector" ), blockingScheduler)
81
- val dao = new Dao (blockingScheduler)
82
98
val settings = new Settings (dao)
83
99
val stateManager = new StateManager (deviceId, cloudConnector, dao, settings)
84
100
@@ -118,9 +134,20 @@ class AppModule(environment: Environment, configuration: Configuration)
118
134
119
135
// startup:
120
136
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
124
151
}
125
152
}
126
153
0 commit comments