-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Description
Brian Gadwell opened SPR-12272 and commented
First a little background:
One way to achieve this is to configure the ThreadPoolTaskExecutor to only use 1 thread. This does indeed work, but at the expense of scalability and performance.
As suggested in the stackoverflow link, this may be able to be handled by using an interceptor to add some type of ordering data to the message header and then using that data to try an re-order the messages when they arrive at the destination. This seems difficult to do correctly.
Now for my solution:
I was able to solve the issue by using an extension of ThreadPoolTaskExecutor that I created that allows for affinity based processing of tasks submitted to the executor. What I mean by this is that handlers can be registered with the executor and the handlers have an opportunity to determine if there is an affinity for the task (runnable) that was submitted. All tasks with the same affinity (just represented as a string) will be guaranteed to be executed in the order they were submitted. In our case, certain destination queues have an affinity and others do not. How long a thread waits for another task to be submitted with a given affinity is configurable, but some short value works well. I feel this is still scalable etc...
Now for the problem and why I am entering this issue:
- There is no easy way to specify a ThreadPoolTaskExecutor to use for the client inbound and outbound channels. I was able to work around this by extending the WebSocketMessageBrokerConfigurationSupport class as opposed to using the
@EnableWebsocketMessageBroker
annotation and extending AbstractWebSocketMessageBrokerConfigurer. If a <? extends ThreadPoolTaskExecutor> could be specified then this would not be a problem. - The tasks in question in this case are ExecutorSubscribableChannel.SendTask, but this is private so I am unable to go from a runnable to something concrete here. If this was public then that would not be a problem.
- Even if ExecutorSubscribableChannel.SendTask was public there is no way to get at the Message and it is the destination in the message headers that I want to examine to determine the affinity. If there was a getter for the Message then this would not be a problem.
I realize my suggestions for changes may not be agreeable and perhaps my solution may not be advisable, but I think it works well. This is a showstopper issue for the project I am working on and I was able to work around the problems by going down a nasty hack route that I would rather avoid. I am hoping the 3 changes above could be accomplished with little controversy.
Affects: 4.1 GA
Reference URL: http://stackoverflow.com/questions/23158928/spring-websocket-sequential-delivery-of-messages-on-clientoutboundchannel-per
Referenced from: commits 44e2921, 521bbfc, 179b236
1 votes, 3 watchers