I have a scenario where two or more subscriptions were made to some entity (with the same notification url). In this case, I have many of the same subscriptions. When the attributes related to subscriptions conditions are updated, I have as many notifications as subscriptions I made. This way, I have unnecessary messages, resulting in unnecessary processing.
Is there a way to deal with this? Both Orion and STH Comet do not handle with this. Maybe Orion and STH can deny the creation of a subscription that already exists. If this Orion behavior is updated, maybe STH Comet does not need to handle that.
This is an issue that has been raised many times, but not fixed yet. It is very easy to create duplicated subscriptions, by mistake for instance, that notify multiple times confusing the notified service ...
Related
I have a requirement to design a notification system for multi-user(~1000 users) application, here are the high level requirements.
System event gets triggered on specific operations.
On event trigger, individual notification for all(or sometimes only for relevant) users gets generated and stored in database.
While user logs in, all unread notifications for him will be pulled and displayed in ui.
While user reads the notification, we capture the read status.
A scheduler in background evicts all the stale notifications.
This seems like a very typical use case and straight forward to implement with the database.
But my doubt is, is there any way we can replace the Database with the Queue based messaging system? The reason I think this way is because, the use case I have seems like asynchronous in nature(like events, notifications and timely eviction of messages).
While I replace the Database with Queues, the first 2 points from above fits well, but on later part I have some doubts -
In General, are queues flexible to store and query notifications based on user ids ?
Consider this scenario - Notifications gets generated and stored in the queue, and the user is not logged in, what is the best way to handle consumer messages.
a. Should the consumer constantly listen for the messages ?, If so should the messages be stored in application memory(does not seems to be good option) ?
b. Or the consumers should be created for each users dynamically on user login? Is this a regular pattern ?
Any other recommended ways ?
Thanks
Your use-case is suited to a database, not a message queue. While conceptually similar to the use case, a message queue is intended for extremely short-duration storage (i.e. to buffer data moving between running processes). Since you have no control over when users log in, these notifications will potentially be stored for minutes, hours, maybe even weeks. You need a persistent storage mechanism.
In some exceptional situations I need somehow to tell consumer on receiving point that some messages shouldn’t be processed. Otherwise two systems will become out-of-sync (we deal with some outdates external systems, and if, for example, connection is dropped we have to discard all queued operations in scope of that connection).
Take a risk and resolve problem messages manually? Compensation actions (that could be tough to support in my case)? Anything else?
There are a few ways:
You can set a time-to-live when sending a message: await endpoint.Send(myMessage, c => c.TimeToLive = TimeSpan.FromHours(1));, but this will apply to all messages that are sent (or published) like this. I would consider this, after looking at your requirements. This is technical, but it is a proper messaging pattern.
Make TTL and generation timestamp properties of your message itself and let the consumer decide if the message is still worth processing. This is more business and, probably, the most correct way.
Combine tech and business - keep the timestamp and TTL in message headers so they don't pollute your message contracts, and filter them out using a custom middleware. In this case, you need to be careful to log such drops so you won't be left wonder why messages disappear now and then.
Almost any unreliable integration can be monitored using sagas, with timeouts. For example, we use a saga to integrate with Twilio. Since we have no ability to open a webhook for them, we poll after some interval to check the message status. You can start a saga when you get a message and schedule a message to check if the processing is still waiting. As discussed in comments, you can either use the "human intervention required" way to fix the issue or let the saga decide to drop the message.
A similar way could be to use a lookup table, where you put the list of messages that aren't relevant for processing. Such a table would be similar to the list of sagas. It seems that this way would also require scheduling. Both here, and for the saga, I'd recommend using a separate receive endpoint (a queue) for the DropIt message, with only one consumer. It would prevent DropIt messages from getting stuck behind the integration messages that are waiting to be processed (and some should be already dropped)
Use RMQ management API to remove messages from the queue. This is the worst method, I won't recommend it.
From what I understand, you're building a system that sends messages to 3rd party systems. In other words, systems you don't control. It has an API but compensating actions aren't always possible, because the API doesn't provide it or because actions are performed inside the 3rd party system that can't be compensated or rolled back?
If possible try to solve this via sagas. Make sure the saga executes the different steps (the sending of messages) in the right order. So that messages that cannot be compensated are sent last. This way message that can be compensated if they fail, will be compensated by the saga. The ones that cannot be compensated should be sent last, when you're as sure as possible that they don't have to be compensated. Because that last message is the last step in synchronizing all systems.
All in all this is one of the problems with distributed systems, keeping everything in sync. Compensating actions is the way to deal with this. If compensating actions aren't possible, you're in a very difficult situation. Try to see if the business can help by becoming more flexible and accepting that you need to compensate things, where they'll tell you it's not possible.
In some exceptional situations I need somehow to tell consumer on receiving point that some messages shouldn’t be processed.
Can't you revert this into:
Tell the consumer that an earlier message can be processed.
This way you can easily turn this in a state machine (like a saga) that acts on two messages. If the 2nd message never arrives then you can discard the 1st after a while or do something else.
The strategy here is to halt/wait until certain that no actions need to be reverted.
using stackdriver's url monitoring.
When it goes down, one time will come but the next will not come.
I would like you to repeatedly notify this if the situation does not change in the next 5 minutes, but I do not know the setting.
somebody help!
https://i.stack.imgur.com/eLROH.png
I'm a product manager with Stackdriver. This is a feature request that we have heard before and are aware of.
This is, unfortunately, not supported at this time, though there are some workarounds:
PagerDuty can be used as a notification channel, and PagerDuty supports repeated notifications.
Webhook can be used as a notification channel, which can be used to create a fully custom delivery mechanism (including one that delivers repeatedly).
Sorry that this isn't available more simply. Hope this helps.
We are using NServicebus to design a system that has to solve an auction scenario: we want to send out a message to a set of companies that can bid on an item. After we've received all the bids we want to send the item to the highest bidder.
We initially thought this kind of scenario was perfectly suited for NServicebus: Pub/sub for sending out a message (e.g. BidOnItem or ItemAvailable), message handlers that subscribe to that message for each interested company and a saga for storing the different bids we receive and we're done.
In a normal auction we could set a timeout at say 5 minutes and then decide who gets the item based on the highest price we've received. We don't have that luxury. The problem that we've run in to is that our specific scenario has a tricky, non-negotiable business requirement: the auction is very time-sensitive. Seconds matter. What we'd like to do is decide who gets the item as soon as all companies have responded. Usually this will happen in a matter of seconds. We want to decide the second all subscribers have responded. Obviously we'll also still implement a timeout but that will be the exception rather than the rule. If we want to determine if everyone has replied we'd need something like a list of all the handlers at all the endpoints that are subscribed to the BidOnItem message. It appears the NServicebus API doesn't provide this information.
There are some future requirements we have to implement as well centered around data enrichment and approval/rejection decisions that would benefit greatly from knowing whether all handlers on a pub/sub channel have responded. I know this reeks of request/reply which is something NServicebus discourages because of the coupling it causes but this requirement feels like something that's fundamental for a lot of processes that is very hard to implement outside of the core bus infrastructure. In that sense it feels a lot like Saga.ReplyToOriginator which NServicebus does provide.
What would be the "NServicebus Way" to solve this problem?
Pub/Sub is usually not the way to go in these auction scenarios. What if your saga would do reguest/response with your bidders?
S: OnAuctionCreated (carries the list of bidders, or you could fetch them somewhere)
foreach bidder in event.Bidders
-bus.Send(RequestBidFrom(bidder))
SetTimeout(X)
S: OnBidResponse
bids.Add(response.Bidder,response.Bid)
if(bids.Count()== Data.TotalBidders)
CompleteAuction();
S:OnTimeout
CompleteAuction()
I have a situation where I have a service subscribing to event messages and performing some work when they arrive. There is a certain class of events which can arrive in short bursts of many events which reference the same underlying data. I would like to be able to defer processing of related events for a short period of time, so that I only do the calculation once for each batch of related events, rather than in response to each individual event. Is there some kind of pattern I can follow which will allow me to collect related events for a period of time and then process them all at once? I was thinking a saga + timeout might be able to achieve this, but not sure if this is an appropriate use for that.
Thanks!
Yes, a saga could be the way to go - however consider the performance of the saga persistence (NHibernate over a DB in the current version, RavenDB in the next version) as compared to your fault-tolerance needs (if a machine crashes, would it be acceptable to lose some messages).
No easy answers, I'm afraid.