All code examples I've seen kind of work like this
subscribe to pullsubscription
get back subscriptionID, watermark
now loop through getEvents() until done, updating watermark
possibly unsubscribe.
In short they assume you are doing the pulling in a single thread/process, and
will not need to again pull using the same watermark/subscription ID again.
The API itself doesn't have a "resumePullScription(subscriptionID,watermark). It just
has beginSubscribe(folders,events,watermark). It's unclear to me whether I can
use that watermark again later with another beginSubscribe, since the subscriptionID
cannot be supplied.
I want to subscribe and get a watermark at time T0
At another time T1, within the timeout interval I want to getEvents again. This is a separate thread, so I need to reconnect to existing subscription/watermark.
It seems like I have two choices for time T1
unsubscribe # time T0,and then resubscribe # time T1 with watermark, but wont watermark be lost because of the unsubscribe?
resubscribe passing just the watermark, but will ews be smart enough to hook up to same subscription? or will watermark be ignored? or will subscription budget grow..?
At any rate it's not actually very clear what happens when subscription expires. I would assume watermark would go, but I see info claiming watermark will survive for 30 days. So then, whats the point of subscription id ?
The PullSubscription class in the EWS Manaaged API doesn't have a constructor to allow you to instantiate it by itself (I guess this was a boarder case in their design). So if you want to do this you would need to use either some ProxyCode eg http://msdn.microsoft.com/en-us/library/office/exchangewebservices.geteventstype(v=exchg.150).aspx or use raw soap and a httpclass to issue the GetEvents request and parse the result.
Basically while the Subscription is valid (eg within the timeout period) you should be able to use GetEvents with the SubscriptionId and a valid watermark (the watermark should be good for the 30 days.If you have unsubscribed the event the watermark wouldn't be valid because it would have been removed from the Events Table.
Cheers
Glen
Related
I have a requirement to update a field if a payment date is 30 days late.
Is it possible to trigger an action to occur 30 days after the payment date?
The process is likely to restart in-between those times so it can't be in-memory and it can't be a relative date.
I can create an endpoint like /api/paymentdates so that it could be called from something else like cron.
However, there are likely to be a over a million items at some point in the future, each with its own date.
Is there an effective way to trigger a task like this or is the only option to run a task every morning and query the database?
You can make use of a Queue Triggered Function (Storage Queue or Service Bus Queue). Basically what you will do is put a message in a queue and keep it invisible for 30 days (it is called initial visibility timeout in storage queue and scheduled message in service bus queue).
The message will only appear in the queue after its invisibility expires and the Function will be triggered at that time. Once the Function is triggered, you can do whatever processing you want to do on that message.
You may find following links useful:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus
Could anyone please elaborate a bit on watermark and its use with respect to recreating subscription using push notification in EWS application?
I read the Microsoft provided information regarding it. But I did not get to understand accurately its usage.
It is explained as:
"The Watermark element represents an event bookmark in the mailbox event queue."
Does it mean that for every event we get new or different watermark in the notification?
Also:
"If a Subscribe request contains a watermark, the subscription is created from the watermark forward."
Does it mean that if we subscribe using a watermark previously sent to us, we can get or identify all the events occurred after it?
Does it mean that for every event we get new or different watermark in the notification?
Yes as the Events are delivered to you client you will get the Water-Mark associated for that event in the Queue.
Does it mean that if we subscribe using a watermark previously sent to us, we can get or identify all the events occurred after it?
Yes if you use a previous watermark your client is telling the server to send the events that occurred after that watermark. Watermarks are valid for 30 days but there are events that can trigger them to become invalid eg
https://blogs.msdn.microsoft.com/exchangedev/2008/07/24/transitioning-to-exchange-web-services-notifications/ . So you need to consider that if you using them for synchronisation.
For the last few years we have used our own RM Application to process events related to our applications. This works by polling a database table every few minutes, looking for any rows that have a due date before now, and have not been processed yet.
We are currently making the transition to SNS, with SQS Worker tiers processing them. The problem with this approach is that we can't future date our messages. Our applications sometimes have events that we don't want to process until a week later.
Are there any design approaches, alternative services, clever tricks we could employ that would allow us to do achieve this?
One solution would be to keep our existing application running, at a simplified level, so all it does is send the SNS notifications when they are due, but the aim of this project is to try and do away with our existing app.
The database approach would be the wisest, being careful that each row is only processed once.
Amazon Simple Notification Service (SNS) is designed to send notifications immediately. There is no functionality for a delayed send (although some notification types are retried if they fail).
Amazon Simple Queue Service (SQS) does have a delay feature, but only up to 15 minutes -- this is useful if you need to do some work before the message is processed, such as copying related data to Amazon S3.
Given that your requirement is to wait until some future arbitrary time (effectively like a scheduling system), you could either start a process and tell it to sleep for a certain amount of time (a bad idea in case systems are restarted), or continue your approach of polling from a database.
If all jobs are scheduled for a distant future (eg at least one hour away), you theoretically only need to poll the database once an hour to retrieve the earliest scheduled time.
A week might be too long as SQS message retention itself is only 15 days. If you are okay with maximum retention of 15days, one idea is to keep the changing the visibility of a message every time you receive until it is ready for processing. The maximum allowed visibility timeout is 12 hours. More on visibility timeout and APIs for changing them,
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibility.html
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/AboutVT.html
I found this approach: https://github.com/alestic/aws-sns-delayed. Basically, you can use a step function with a wait step in there
I have an requirement where I have to send the alerts when the record in db is not updated/changed for specified intervals. For example, if the received purchase order doesn't processed within one hour, the reminder should be sent to the delivery manager.
The reminder/alert should sent exactly at the interval (including seconds). If the last modified time is 13:55:45 means, the alert should be triggered 14:55:45. There could be million rows needs to be tracked.
The simple approach could be implementing a custom scheduler and all the records will registered with it. But should poll the database to look for the change every second and it will lead to performance problem.
UPDATE:
Another basic approach would be a creating a thread for each record and put it on sleep for 1 hour (or) Use some queuing concept which has timeout. But still it has performance problems
Any thoughts on better approach to implement the same?
probably using internal JMS queue would be better solution - for example you may want to use scheduled message feature http://docs.jboss.org/hornetq/2.2.2.Final/user-manual/en/html/examples.html#examples.scheduled-message with hornetq.
You can ask broker to publish alert message after exactly 1h. From the other hand during processing of some trading activity you can manually delete this message meaning that the trade activity has been processed without errors.
Use Timer for each reminder.i.e. If the last modified time is 17:49:45 means, the alert should be triggered 18:49:45 simply you should create a dynamic timer scheduling for each task it'll call exact after one hour.
It is not possible in Java, if you really insist on the "Real-timeness". In Java you may encouter Garbage collector's stop-the-world phase and you can never guarantee the exact time.
If the approximate time is also permissible, than use some kind of scheduled queue as proposed in other answers, if not, than use real-time Java or some native call.
If we can assume that the orders are entered with increasing time then:
You can use a Queue with elements that have the properties time-of-order and order-id.
Each new entry that is added to the DB is also enqueued to this Queue.
You can check the element at the start of the Queue each minute.
When checking the element at the start of the Queue, if an hour has passed from the time-of-order, then search for the entry with order-id in the DB.
If found and was not updated then send a notification, else dequeue it from the Queue .
I think this is a solved problem but my google-fu wasn't good enough.
I have a table tracking the status of multiple things. Server can push changes to clients at will.
The problem is I don't want to push update if the last update is less than 5 seconds ago.
What is the cleanest way of achieving this without making another event manager thread?
My current stab looks like this:
pushEvent(){
Look up the last update time
if: last update less than 5 sec ago
then do nothing
else
pushToClients
}
It works good enough for most part, but obviously the last update could be left unpushed.
What is a good way of doing this?
Some ways I have thought of:
Add a 5 second delay to all push (eg Thread.sleep), that way I can
check if an update has already been scheduled. Not ideal but no one
would mind.
Do the push, then set doNotPush=true. Use a timer to
set it back to false.
Thanks,
On server, you can use HashMap which will contain pair {current event, last sent event} as values and event's recepients (clients) as keys. Then use scheduled periodic task which will iterate over this map, check if current event != last sent event and, if yes, will send current event to client (and put it intolast sent).
One drawback can be that if sending to client is slow, there can be jams of events in outgoing queues. You can work around this by sending asynchronously (e.g., by offloading events to be sent into separate Executor).