Skip to content

Conversation

@arturaz
Copy link
Collaborator

@arturaz arturaz commented Feb 11, 2025

So... remember this: io.lettuce.core.RedisCommandTimeoutException: Command timed out after 1 minute(s) ?

After building lettuce with a patch to include command name in the timeout message it turned out that the timeouting command is SUBSCRIBE, which was weird. Until I looked at the code that does the subscription.

These seems to be buggy:

override def subscribe(channel: RedisChannel[K]): Stream[F, V] =
Stream
.resource(Resource.eval(state.get) >>= PubSubInternals.channel[F, K, V](state, subConnection).apply(channel))
.evalTap(_ =>
FutureLift[F]
.lift(subConnection.async().subscribe(channel.underlying))
)
.flatMap(_.subscribe(500).unNone)

override def psubscribe(
pattern: RedisPattern[K]
): Stream[F, RedisPatternEvent[K, V]] =
Stream
.resource(Resource.eval(state.get) >>= PubSubInternals.pattern[F, K, V](state, subConnection).apply(pattern))
.evalTap(_ =>
FutureLift[F]
.lift(subConnection.async().psubscribe(pattern.underlying))
)
.flatMap(_.subscribe(500).unNone)

  • You can't do state.get from a Ref and expect that state to hold while you go on to perform side-effects.
  • Usage of .unNone is highly questionable, it just filters out None's, I guess this was intended to be unNoneTerminate.
  • The logic was generally hard to follow. There is one Topic shared between multiple streams, but each subscribe gets it's own redis listener and Dispatcher? Why?

So I rewrote the logic to:

  • Maintain separate AtomicCell state maps for channels and patterns.
  • Create a new subscription, topic and Dispatcher first time someone subscribes to channel or pattern.
  • In case someone subscribes to the same thing again the subscriber count is increased.
  • Subscriber count is decreased when the Stream is terminated.
  • unsubscribe finishes all Streams.
  • Cleanup is performed when the last stream terminates.

I also changed the return type of publish to match the type from Lettuce.

@yisraelU I would appreciate you double-checking the logic here.

@yisraelU
Copy link
Collaborator

looks good

@arturaz arturaz merged commit ae024bb into series/1.x Feb 12, 2025
2 checks passed
@arturaz arturaz deleted the fix/race-conditions-in-pubsub branch February 12, 2025 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants