@@ -66,45 +66,53 @@ class JdkAutoUpdatingVar[T](
66
66
override def latest : T = variable.getOrElse(throw UnreadyAutoUpdatingVarException )
67
67
68
68
override def close (): Unit = {
69
- nextTask.cancel(true )
69
+ CloseLock .synchronized {
70
+ closed = true
71
+ nextTask.foreach(_.cancel(true ))
72
+ }
70
73
if (executorOverride.isEmpty)
71
74
executor.shutdownNow()
72
75
super .close()
73
76
}
74
77
78
+ private case object CloseLock
79
+
80
+ @ volatile private var closed = false
81
+
75
82
@ volatile private var variable : Option [T ] = None
76
83
77
84
private val _ready = Promise [Unit ]()
78
85
79
- @ volatile private var nextTask : ScheduledFuture [_] =
80
- executor.schedule(
81
- new Runnable {
82
- def run () : Unit = {
83
- val tryV =
84
- Try ( try {
85
- try {
86
- updateVar
87
- } catch {
88
- case NonFatal (e) =>
89
- log.error(logString( " Failed to initialize var " ), e)
90
- throw e
91
- }
92
- } catch (handleInitializationError))
93
-
94
- tryV match {
95
- case Success (value) =>
96
- variable = Some (value)
97
- _ready.complete( Success (()) )
98
- log.info(logString( " Successfully initialized " ))
99
- scheduleUpdate(updateInterval.duration(value ))
100
- case Failure (e) =>
101
- _ready.complete( Failure (e))
102
- }
86
+ @ volatile private var nextTask : Option [ ScheduledFuture [_]] = None
87
+
88
+ executor.schedule(
89
+ new Runnable {
90
+ def run () : Unit = {
91
+ val tryV =
92
+ Try ( try {
93
+ try {
94
+ updateVar
95
+ } catch {
96
+ case NonFatal (e) =>
97
+ log.error(logString( " Failed to initialize var " ), e)
98
+ throw e
99
+ }
100
+ } catch (handleInitializationError))
101
+
102
+ tryV match {
103
+ case Success (value) =>
104
+ variable = Some (value )
105
+ _ready.complete( Success (() ))
106
+ log.info(logString( " Successfully initialized " ))
107
+ scheduleUpdate(updateInterval.duration(value))
108
+ case Failure (e) =>
109
+ _ready.complete( Failure (e))
103
110
}
104
- },
105
- 0 ,
106
- TimeUnit .NANOSECONDS
107
- )
111
+ }
112
+ },
113
+ 0 ,
114
+ TimeUnit .NANOSECONDS
115
+ )
108
116
109
117
blockUntilReadyTimeout.foreach { timeout =>
110
118
Await .result(ready, timeout)
@@ -113,7 +121,10 @@ class JdkAutoUpdatingVar[T](
113
121
private def scheduleUpdate (nextUpdate : FiniteDuration ): Unit = {
114
122
log.info(logString(s " Scheduling update of var in: $nextUpdate" ))
115
123
116
- nextTask = executor.schedule(new UpdateVar (1 ), nextUpdate.length, nextUpdate.unit)
124
+ CloseLock .synchronized {
125
+ if (! closed)
126
+ nextTask = Some (executor.schedule(new UpdateVar (1 ), nextUpdate.length, nextUpdate.unit))
127
+ }
117
128
()
118
129
}
119
130
@@ -144,11 +155,17 @@ class JdkAutoUpdatingVar[T](
144
155
logString(s " Unhandled exception when trying to update var, retrying in $delay" ),
145
156
e
146
157
)
147
- executor.schedule(
148
- new UpdateVar (attempt + 1 ),
149
- delay.length,
150
- delay.unit
151
- )
158
+
159
+ CloseLock .synchronized {
160
+ if (! closed)
161
+ nextTask = Some (
162
+ executor.schedule(
163
+ new UpdateVar (attempt + 1 ),
164
+ delay.length,
165
+ delay.unit
166
+ )
167
+ )
168
+ }
152
169
()
153
170
}
154
171
}
0 commit comments