@@ -10,6 +10,7 @@ import com.avsystem.commons.redis._
10
10
import com .avsystem .commons .redis .commands .{PubSubCommand , PubSubEvent , ReplyDecoders }
11
11
import com .avsystem .commons .redis .config .ConnectionConfig
12
12
import com .avsystem .commons .redis .exception ._
13
+ import com .avsystem .commons .redis .monitoring .{ConnectionState , ConnectionStateObserver }
13
14
import com .avsystem .commons .redis .protocol .{RedisMsg , RedisReply , ValidRedisMsg }
14
15
import com .avsystem .commons .redis .util .ActorLazyLogging
15
16
@@ -20,8 +21,11 @@ import scala.collection.mutable
20
21
import scala .concurrent .duration .Duration
21
22
import scala .util .Random
22
23
23
- final class RedisConnectionActor (address : NodeAddress , config : ConnectionConfig )
24
- extends Actor with ActorLazyLogging { actor =>
24
+ final class RedisConnectionActor (
25
+ address : NodeAddress ,
26
+ config : ConnectionConfig ,
27
+ connectionStateObserver : OptArg [ConnectionStateObserver ] = OptArg .Empty ,
28
+ ) extends Actor with ActorLazyLogging { actor =>
25
29
26
30
import RedisConnectionActor ._
27
31
import context ._
@@ -56,7 +60,7 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
56
60
handlePacks(packs)
57
61
case open : Open =>
58
62
onOpen(open)
59
- become(connecting (config.reconnectionStrategy, Opt .Empty ))
63
+ become(watchedConnecting (config.reconnectionStrategy, Opt .Empty ))
60
64
self ! Connect
61
65
}
62
66
@@ -95,6 +99,11 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
95
99
}
96
100
}
97
101
102
+ private def watchedConnecting (retryStrategy : RetryStrategy , readInitSender : Opt [ActorRef ]): Receive = {
103
+ connectionStateObserver.foreach(_.onConnectionStateChange(address, ConnectionState .Connecting ))
104
+ connecting(retryStrategy, readInitSender)
105
+ }
106
+
98
107
private def connecting (retryStrategy : RetryStrategy , readInitSender : Opt [ActorRef ]): Receive = {
99
108
case open : Open =>
100
109
onOpen(open)
@@ -128,7 +137,7 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
128
137
case ReadInit =>
129
138
// not sure if it's possible to receive ReadInit before Connected but just to be safe
130
139
// delay replying with ReadAck until Connected is received
131
- become(connecting (retryStrategy, Opt (sender())))
140
+ become(watchedConnecting (retryStrategy, Opt (sender())))
132
141
case _ : TcpEvent => // ignore, this is from previous connection
133
142
}
134
143
@@ -197,7 +206,7 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
197
206
if (delay > Duration .Zero ) {
198
207
log.info(s " Next reconnection attempt to $address in $delay" )
199
208
}
200
- become(connecting (nextStrategy, Opt .Empty ))
209
+ become(watchedConnecting (nextStrategy, Opt .Empty ))
201
210
system.scheduler.scheduleOnce(delay, self, Connect )
202
211
case Opt .Empty =>
203
212
close(failureCause, stopSelf = false )
@@ -282,7 +291,7 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
282
291
config.initCommands.decodeReplies(packsResult)
283
292
log.debug(s " Successfully initialized Redis connection $localAddr-> $remoteAddr" )
284
293
initPromise.trySuccess(())
285
- become(ready )
294
+ become(watchedReady )
286
295
writeIfPossible()
287
296
} catch {
288
297
// https://github.com/antirez/redis/issues/4624
@@ -301,6 +310,11 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
301
310
close(new ConnectionInitializationFailure (cause), stopSelf = false )
302
311
}
303
312
313
+ def watchedReady : Receive = {
314
+ connectionStateObserver.foreach(_.onConnectionStateChange(address, ConnectionState .Connected ))
315
+ ready
316
+ }
317
+
304
318
def ready : Receive = {
305
319
case open : Open =>
306
320
onOpen(open)
@@ -338,7 +352,7 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
338
352
case open : Open =>
339
353
onOpen(open)
340
354
initPromise.success(())
341
- become(ready )
355
+ become(watchedReady )
342
356
case IncomingPacks (packs) =>
343
357
packs.reply(PacksResult .Failure (cause))
344
358
case Release => // ignore
@@ -512,7 +526,7 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
512
526
if (stopSelf) {
513
527
stop(self)
514
528
} else {
515
- become(closed (cause, tcpConnecting))
529
+ become(watchedClosed (cause, tcpConnecting))
516
530
}
517
531
}
518
532
@@ -522,11 +536,16 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
522
536
drain(queuedToReserve)(_.reply(failure))
523
537
}
524
538
539
+ private def watchedClosed (cause : Throwable , tcpConnecting : Boolean ): Receive = {
540
+ connectionStateObserver.foreach(_.onConnectionStateChange(address, ConnectionState .Closed ))
541
+ closed(cause, tcpConnecting)
542
+ }
543
+
525
544
private def closed (cause : Throwable , tcpConnecting : Boolean ): Receive = {
526
545
case open : Open =>
527
546
onOpen(open)
528
547
incarnation = 0
529
- become(connecting (config.reconnectionStrategy, Opt .Empty ))
548
+ become(watchedConnecting (config.reconnectionStrategy, Opt .Empty ))
530
549
if (! tcpConnecting) {
531
550
self ! Connect
532
551
}
@@ -536,11 +555,19 @@ final class RedisConnectionActor(address: NodeAddress, config: ConnectionConfig)
536
555
case Connected (connection, _, _, _) if tcpConnecting =>
537
556
// failure may have happened while connecting, simply close the connection
538
557
connection ! CloseConnection (immediate = true )
539
- become(closed (cause, tcpConnecting = false ))
558
+ become(watchedClosed (cause, tcpConnecting = false ))
540
559
case _ : TcpEvent => // ignore
541
560
case Close (_, true ) =>
542
561
stop(self)
543
562
}
563
+
564
+ override def preStart (): Unit = {
565
+ connectionStateObserver.foreach(_.onConnectionStateChange(address, ConnectionState .Created ))
566
+ }
567
+
568
+ override def postStop (): Unit = {
569
+ connectionStateObserver.foreach(_.onConnectionStateChange(address, ConnectionState .Removed ))
570
+ }
544
571
}
545
572
546
573
object RedisConnectionActor {
0 commit comments