Skip to content
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

Allow customizing of DefaultSubscriptionRegistry messageEvalContext [SPR-17485] #22017

Open
spring-issuemaster opened this issue Nov 11, 2018 · 7 comments

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Nov 11, 2018

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

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 12, 2018

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?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 12, 2018

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.

 

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 12, 2018

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.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 12, 2018

David Melia commented

Hi Rossen Stoyanchev

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

 

 

 

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 12, 2018

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.

 

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 13, 2018

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

 

 

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 14, 2018

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.

 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.