Skip to content

Commit

Permalink
Safely add and register the MessageListener to Topic mapping.
Browse files Browse the repository at this point in the history
Given addListener(:MessageListener, :Collection<Topic>) could be called concurrently from the addMessageListener(:MessageListener, Collection<Topic>) method by multiple Threads, and the RedisMessageListenerContainer Javadoc specifically states that it is safe to call the addMessageListener(..) method conurrently without any external synchronization, and the registeration (or mapping) of listener to Topics is a componund action, then a race condition is possible.

Closes #2755
  • Loading branch information
jxblum committed Oct 23, 2023
1 parent 963bc92 commit f8c699b
Showing 1 changed file with 5 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -612,20 +612,17 @@ private void initMapping(Map<? extends MessageListener, Collection<? extends Top

private void addListener(MessageListener listener, Collection<? extends Topic> topics) {

Assert.notNull(listener, "a valid listener is required");
Assert.notEmpty(topics, "at least one topic is required");
Assert.notNull(listener, "A valid listener is required");
Assert.notEmpty(topics, "At least one topic is required");

List<byte[]> channels = new ArrayList<>(topics.size());
List<byte[]> patterns = new ArrayList<>(topics.size());

boolean trace = logger.isTraceEnabled();

// add listener mapping
Set<Topic> set = listenerTopics.get(listener);
if (set == null) {
set = new CopyOnWriteArraySet<>();
listenerTopics.put(listener, set);
}
// safely lookup or add MessageListener to Topic mapping
Set<Topic> set = listenerTopics.computeIfAbsent(listener, key -> new CopyOnWriteArraySet<>());

set.addAll(topics);

for (Topic topic : topics) {
Expand Down

0 comments on commit f8c699b

Please sign in to comment.