Multithreaded PublishService

Hello all,

I have a question, we encountered an issue in our service, with regard to multithreading and the PublishService. Our code looked like this roughly:

PublishService publishService = Services.publishService();

for (Message message : messages) {
    executorService.submit(message -> publishMessage(publishService, message).join() );
}

It turns out that the code in the PublishService is not thread-safe. This particular problem was fixed by doing

var list = new ArrayList<CompletableFuture<?>>();
for (Message message : messages) {
    list.append(publishMessage(publishService, message));
}

CompletableFuture.allOf(list.toArray()).join();

I added a test for it, and I haven’t seen it going wrong since, it also makes more sense IMO.

However, this got me thinking about mutliple threads calling Services.publishService()#publish and publishing at the same time. Is this something that is doable? I was looking at the code, but it is unclear to me, especially since there is some non-trivial way in which the Services class returns its objects.

How would I have to do this in production, would I need to have a global lock somewhere, so that there is only 1 publish call at the same time, or can I freely create multiple PublishServices and publish at the same time?

Thanks in advance,

Bram

Is there someone that might be able to shed some light on this? I want to be sure that I’m not having some very subtle concurrency issues on my broker.

Hello @basimons ,

Thank you for the outreach!

We would be happy to assist. In coordination with our internal engineering teams, I wanted to reach out here to verify if you would be able to offer a minimal reproducer for this issue for our teams to review directly.

This will allow us to review the issue internally with the reproducer directly, and act accordingly.

Best,
Aaron from the HiveMQ Team

Thanks for your reaction, I do have a reproducible example, but currently it is embedded into our whole server so I cannot share that with you.

I can extract some of it, to make a standalone reproducible example, however I don’t have time for currently, I might be able to squeeze it inbetween some other things, but I’m unsure.

I’ll send you the example asap, but this might also be in a few weeks.

Thanks,

Bram