-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make PubSubState
a trait
#972
base: series/1.x
Are you sure you want to change the base?
Make PubSubState
a trait
#972
Conversation
@arturaz Since this mostly refactors the code that you recently wrote, I think it is only fair to ask you if you think if this change is an improvement or not? And if you think it is an improvement in general, if you have any feedback? |
Yeah, this needs to be benchmarked. We could be complicating the code with no real benefit.
What about this scenario? Last subscriber is unsubscribing. It is removed from AtomicCell and then proceeds to run cleanup. However, Cats Effect scheduler decides to yield between |
I also think the debug logs should be left there, they are useful when, well, debugging :) |
Thanks for taking a look, @arturaz!
I agree I should have done some testing before. A simple test opening and closing some subscriptions in parallel, does already show the contention. I'll see if I can spend some more time creating some better benchmarks. test("subscribe and unsubscribe ") {
import cats.syntax.all._
withRedisPubSub { pubSub =>
val channels = List.range(1, 100).map(_ % 25).map(n => RedisChannel(n.toString))
val expectedSubscriptions = channels.length.toLong
val checkSubscriptionCount: IO[Long] = pubSub.internalChannelSubscriptions.map(_.values.sum)
val wait = checkSubscriptionCount
.delayBy(50.millis)
.iterateUntil(_ == expectedSubscriptions)
val subscribe = channels.parTraverse { channel =>
pubSub.subscribe(channel).compile.drain
}
val unsubscribe = channels.parTraverse(pubSub.unsubscribe)
IO.both(subscribe, wait >> unsubscribe).timed.flatMap { case (d, _) => IO.println(d) }
}
} Switching to use
I can bring those back. I may try to see if we can add them back while keeping them outside of |
Is there any downside in only having the sharded implementation? |
Represent start up and clean up as state changes
Probably not. Thinking about this more, I think we can still make a |
So I should delay my review until you finish, right? |
I opened #984 to replace this PR (but I'll leave this one open for now). |
An attempt to make it easier to change the
PubSubState
implementation or add multiple implementations. This is somewhat of a follow up of #966.For some context: I am exploring using keyspace notifications and that led me to look at the pubsub code. My usecase would have a lot of short lived subscriptions, which is probably not the most common pubsub usage. Without any real tests or digging deeper into the lettuce code, I was somewhat worried about contention on a single
AtomicCell
holding all subscriptions (but it could be completely unfounded).I hope that the change in this PR makes it easier to make the
PubSubState
more configurable. I added a shardedPubSubState
implementation that is currently unused and only shows how we could support different implementations (but it seems a useful implementation to have).Subscriber
code intoPubSubState
. The first one now mostly contains how to create a subscription, while the second one now maintains (and hides) the subscription lifecycle.