17
17
package dev .profunktor .redis4cats .pubsub .internals
18
18
19
19
import scala .util .control .NoStackTrace
20
-
21
- import cats .effect .kernel .{ Async , Ref , Resource , Sync }
22
- import cats .effect .std .Dispatcher
23
- import cats .syntax .all ._
20
+ import cats .effect .std .{ Dispatcher }
24
21
import dev .profunktor .redis4cats .data .RedisChannel
25
22
import dev .profunktor .redis4cats .data .RedisPattern
26
23
import dev .profunktor .redis4cats .data .RedisPatternEvent
27
- import dev .profunktor .redis4cats .effect .Log
28
- import fs2 .concurrent .Topic
29
- import io .lettuce .core .pubsub .{ RedisPubSubListener , StatefulRedisPubSubConnection }
24
+ import io .lettuce .core .pubsub .{ RedisPubSubListener }
30
25
import io .lettuce .core .pubsub .RedisPubSubAdapter
31
26
32
27
object PubSubInternals {
33
28
case class DispatcherAlreadyShutdown () extends NoStackTrace
34
29
35
- private [redis4cats] def channelListener [F [_]: Async , K , V ](
30
+ private [redis4cats] def channelListener [F [_], K , V ](
36
31
channel : RedisChannel [K ],
37
- topic : Topic [ F , Option [ V ] ],
32
+ publish : V => F [ Unit ],
38
33
dispatcher : Dispatcher [F ]
39
34
): RedisPubSubListener [K , V ] =
40
35
new RedisPubSubAdapter [K , V ] {
41
36
override def message (ch : K , msg : V ): Unit =
42
37
if (ch == channel.underlying) {
43
38
try {
44
- dispatcher.unsafeRunSync(topic.publish1( Option ( msg)).void )
39
+ dispatcher.unsafeRunSync(publish( msg))
45
40
} catch {
46
41
case _ : IllegalStateException => throw DispatcherAlreadyShutdown ()
47
42
}
@@ -50,65 +45,19 @@ object PubSubInternals {
50
45
// Do not uncomment this, as if you will do this the channel listener will get a message twice
51
46
// override def message(pattern: K, channel: K, message: V): Unit = {}
52
47
}
53
- private [redis4cats] def patternListener [F [_]: Async , K , V ](
48
+ private [redis4cats] def patternListener [F [_], K , V ](
54
49
redisPattern : RedisPattern [K ],
55
- topic : Topic [ F , Option [ RedisPatternEvent [K , V ]] ],
50
+ publish : RedisPatternEvent [K , V ] => F [ Unit ],
56
51
dispatcher : Dispatcher [F ]
57
52
): RedisPubSubListener [K , V ] =
58
53
new RedisPubSubAdapter [K , V ] {
59
54
override def message (pattern : K , channel : K , message : V ): Unit =
60
55
if (pattern == redisPattern.underlying) {
61
56
try {
62
- dispatcher.unsafeRunSync(topic.publish1( Option ( RedisPatternEvent (pattern, channel, message))).void )
57
+ dispatcher.unsafeRunSync(publish( RedisPatternEvent (pattern, channel, message)))
63
58
} catch {
64
59
case _ : IllegalStateException => throw DispatcherAlreadyShutdown ()
65
60
}
66
61
}
67
62
}
68
-
69
- private [redis4cats] def channel [F [_]: Async : Log , K , V ](
70
- state : Ref [F , PubSubState [F , K , V ]],
71
- subConnection : StatefulRedisPubSubConnection [K , V ]
72
- ): GetOrCreateTopicListener [F , K , V ] = { channel => st =>
73
- st.channels
74
- .get(channel.underlying)
75
- .fold {
76
- for {
77
- dispatcher <- Dispatcher .parallel[F ]
78
- topic <- Resource .eval(Topic [F , Option [V ]])
79
- _ <- Resource .eval(Log [F ].info(s " Creating listener for channel: $channel" ))
80
- listener = channelListener(channel, topic, dispatcher)
81
- _ <- Resource .make {
82
- Sync [F ].delay(subConnection.addListener(listener)) *>
83
- state.update(s => s.copy(channels = s.channels.updated(channel.underlying, topic)))
84
- } { _ =>
85
- Sync [F ].delay(subConnection.removeListener(listener)) *>
86
- state.update(s => s.copy(channels = s.channels - channel.underlying))
87
- }
88
- } yield topic
89
- }(Resource .pure)
90
- }
91
-
92
- private [redis4cats] def pattern [F [_]: Async : Log , K , V ](
93
- state : Ref [F , PubSubState [F , K , V ]],
94
- subConnection : StatefulRedisPubSubConnection [K , V ]
95
- ): GetOrCreatePatternListener [F , K , V ] = { channel => st =>
96
- st.patterns
97
- .get(channel.underlying)
98
- .fold {
99
- for {
100
- dispatcher <- Dispatcher .parallel[F ]
101
- topic <- Resource .eval(Topic [F , Option [RedisPatternEvent [K , V ]]])
102
- _ <- Resource .eval(Log [F ].info(s " Creating listener for pattern: $channel" ))
103
- listener = patternListener(channel, topic, dispatcher)
104
- _ <- Resource .make {
105
- Sync [F ].delay(subConnection.addListener(listener)) *>
106
- state.update(s => s.copy(patterns = s.patterns.updated(channel.underlying, topic)))
107
- } { _ =>
108
- Sync [F ].delay(subConnection.removeListener(listener)) *>
109
- state.update(s => s.copy(patterns = s.patterns - channel.underlying))
110
- }
111
- } yield topic
112
- }(Resource .pure)
113
- }
114
63
}
0 commit comments