David Melia opened SPR-17485 and commented
Hi,
org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry contains
private static EvaluationContext messageEvalContext =
SimpleEvaluationContext.forPropertyAccessors(new SimpMessageHeaderPropertyAccessor()).build();
but with no way to override it.
If you think about a stock broking site contain 1000s of price updates I need the ability to add a selector header to filter only the stocks that the customer is interested in. To do that using the default cut down EvaluationContext the selector would be very clunky.
If I can add my own function to the evaluation context i.e
messageEvalContext.setVariable("myCustomStockSymbolFilterFunction" . . .
then the selector would be simplified i.e.
#myCustomStockSymbolFilterFunction(headers['simpDestination'],{'MSFT','BARC'})
Therefore: * Could you add the ability to override the EvaluationContext?
- If so would it be possible to make SimpMessageHeaderPropertyAccessor available somehow?
Thanks
Affects: 5.1.2
Comment From: spring-projects-issues
Juergen Hoeller commented
In order to preserve the common SimpMessageHeaderPropertyAccessor
for those purposes, maybe a template method along the lines of protected void customizeEvaluationContext
would make sense, not replacing the default setup but just adding variables to it? Do you see any further need for a custom EvaluationContext
instance, potentially switching to a StandardEvaluationContext
or the like?
Comment From: spring-projects-issues
David Melia commented
It is possible that others may want full control but for my own needs a template sounds great as long as I can add a custom function
messageEvalContext.setVariable("myCustomStockSymbolFilterFunction" . . .
Thanks Juergen.
Comment From: spring-projects-issues
Rossen Stoyanchev commented
David Melia, I'm wondering if you considered destination patterns as a way for subscribers to narrow what they're interested in? Like in the spring-portfolio sample, subscribing and broadcasting.
Comment From: spring-projects-issues
David Melia commented
Thanks for the spring-portfolio sample which is providing the basis of my prototype but I noticed that all prices are being pushed back to the browser regardless if that user has them or not which would be a problem for us.
My requirement is to provide streaming prices for thousands of stocks from around the world. Customers will have a mixed portfolio and we don't want to segment it into UK, US, Canada, etc. This is why I struggled to narrow the subscription for this type of stock. I could either 1. Have a topic per instrument i.e. /topic/price.stock.MSFT, /topic/price.stock.BARC, /topic/price.stock.AZN, etc 2. Have a topic for all instruments /topic/price.stock.* but filter with a selector.
I thought 2 was the best approach which is when I noticed that I needed to raise this issue.
Any thoughts are welcome :)
Thanks
Comment From: spring-projects-issues
Rossen Stoyanchev commented
Yes the sample was meant to show 1) with "topic per instrument". At any given time the broker has as many topics as the number of instruments in the portfolios of connected customers, which perhaps won't be as many as all the stocks that exist.
Another option to consider would be to create an individual queue for each customer portfolio. The code pushing stock updates could then check which users are connected through the SimpUserRegistry
and push updates to the queues of those whose portfolios contain a stock.
Comment From: spring-projects-issues
David Melia commented
That's interesting. Let's say each customer has 100 unique instruments on screen at any one time. Also assume that we keep the topic /topic/price.stock.*
I thought creating 100 stomp JS instrument subscriptions from the browser would be the wrong thing to do i.e using your prototype I would do something like
// controller.js
tradeService.connect("/portfolio")
. . . .
angular.forEach($scope.positions, function(value, key){
tradeService.fetchQuoteStream(key).then(null, null,
function(quote) {
processQuote(quote);
}
);
});
Rossen Stoyanchev Is the above multiple Stomp JS subscription the recommended way to achieve instrument subscriptions than the message selector way? Would there be a performance cost?
Thanks
Comment From: spring-projects-issues
Rossen Stoyanchev commented
David Melia it's difficult to say that generally, because the answer will vary based on number of customers x tickers, as well as usage patterns, but I wouldn't discount this as an option.
DefaultSubscriptionRegistry
maintains a cache of previously matched subscription destinations. By default that's set to 1024, but you can configure it in the Java config through the MessageBrokerRegistry
. If the lookups are cached, I don't think the rest is very different since you have to deliver a message per picker regardless how the subscriptions are laid out.