Esper EPL - Differentiate deleted events from released events in a timed window - esper

I count events within a timed window. If more than 5 events arrive at that window, then I want to discard them all. Otherwise, the events are released after the waiting time.
My code goes something like this:
// Create a timed window of 10 seconds
create window MyWindow.win:time(10 sec) as MyEventType;
// Add to the timed window
insert into MyWindow select * from MyEventType;
//Delete from window if upper limit was reached
On MyEventType as newEvent
select and delete * from MyWindow as oldEvent
having COUNT(*) >= 5;
Additionally, a listener receives all events that leave the timed window:
select rstream * from MyWindow;
The problem with the example above is that both deleted and released events are forwarded to the listener (via rstream).
Question: how to differentiate deleted events from released ones?

There is nothing on the events afaik. I think an application could look at the time of the event and see if its older than current time. I can think of another option whereas a listener of on-delete receives the deleted events and not the expired ones which given the application a means to know what was deleted and what was expired.

Related

How do I delay clearing a ThingsBoard alarm?

I have a rule chain in ThingsBoard that does a Create Alarm when temperature is outside threshold and does a Clear Alarm otherwise. I receive a message using a Telegram bot when these events occur. That all works fine.
However when the temperature is hovering around the threshold, I can get many notifications as it goes in and out of the threshold temperature. That is somewhat annoying.
I would like to have the Clear Alarm activity only trigger if it is more than 5 minutes (say) since the last Create Alarm event was triggered.
Any tips on how to achieve this?
I finally worked out how to do this.
I added some server attributes to my device that define the temperatures that trigger alarms. I have a rule chain for controlling these alarms with the following nodes:
Enrichment - originator attributes to add the relevant attributes into the metadata associated with this message
Filter - script to detect if the temperature is outside the expected range
Filter - script to detect if the delay period has expired since the last time the alarm was triggered
Action - create alarm when script detects that temp is out of range
Action - clear alarm when script detects that delay period has expired
Transformation - script to update last alarm time attribute
Action - save attributes to persist updated alarm time attribute
Transformation - script to create a message about alarm set or cleared
Rule chain to handle sending the message to a Telegram bot
As an example, here is the script for checking if the delay period has expired before clearing the alarm:
var alarmTime = Number(metadata.ss_lastWaterTempAlarmTime);
var alarmDelay = Number(metadata.ss_clearAlarmTimeDelay);
return metadata.ts >= alarmDelay + alarmTime;
ss is the prefix added for server side attributes that have been added to metadata.
You can see the complete rule chain json in my Aquamon repo.

Why does .share() have no effect on cold sources (autoconnect vs. refCount)?

Flux<Integer> shared = Flux.just(1, 2).share();
shared.subscribe(System.out::println);
shared.subscribe(System.out::println);
Since share() turns the flux into a hot one, I expect the first subscriber to get all values and the second one to get none, since the stream has completed at the time of subscription. But the output is the same as without share: 1 2 1 2, but it should be just 1 2.
When I replace share() with publish.autoconnect() it works as expected. Why is that?
The answer is simple, but it took me a while to figure it out.
share() is a shortcut for publish().refCount(). refCount() is like autoConnect() except for one additional feature: It disconnects when all subscribers have cancelled or - and that's the situation here - the stream has completed.
The first shared.subscribe creates a subscription (via share) to the original flux. All values are emitted immediately, the stream completes, the subscription is cancelled.
Since there is no subscription now, the second shared.subscribe again creates a subscription and the stream starts again, from the beginning.
autoConnect, however, does not cancel the subscription. If you use it instead of refCount the subscription to the original flux remains, but because the stream has completed, any additional subscriber won't receive any values.

Eseper event timeout

I want to timeout events individually for each incoming event in esper. How to achieve that?
If i use time or batch windows, it will wait for other events to first fill the window ,only then the events are moved to rstream.
Use a named window with keep-all and put the condition when events get deleted into an on-delete.
create window CustomExpiryWindow.win:keepall() as MyEvent
insert into CustomExpiryWindow select * from MyEvent
on <.......> delete from CustomExpiryWindow where <......>
In Alternative there is an extension API for data windows where you could write code to keep and expire events.

Reminder using Signal R

I have a reminder functionality using signal R in asp.net mvc
I have userinterface to set the reminder time, If the current time matches the reminder time , it invokes a popup.
I successfully implemented this functionality with Signal R by checking the database once in every 30 seconds by using javascript timer. If current time does not match, it gives '0'.If it matches, it return '1' and the popup is shown across all browsers. But can this checking the db for every 30 seconds can be replaced by signal R ? is there any way to bring this whole thing to signal R?
You can use System.Threading.Timer to create a periodical method call to both client and server side. According to Sample project created for stocks
_timer = new Timer(UpdateStockPrices, null, _updateInterval, _updateInterval);
It creates and Event-Delegate and calls UpdateStockPrices event timely with period of __updateInterval.
In This event(code given below) you can broadcast the remainder message from server to all clients or clients who are associated with that remainder.
You can write code as :-
Clients.All.updateStockPrice(stock);
You can refer to Timer from link:-
http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx
Yes, you can use Timer in the appdomain scope, application scope or at the hub level. Just get the sample from nuget, called "Microsoft.AspNet.SignalR.Sample". It implements stock timer that periodically broadcasts changes to all clients.

Polly show dialog after retry count reached

I'm using Polly to retry web service calls in case the call fails with WebException, because I want to make sure the method executed correctly before proceeding. However sometimes web methods still throw exception even after retrying several times and I don't want to retry forever. Can I use Polly to show some confirmation dialog, e.g. "Max retry count reached! Make sure connection is enabled and press retry." Then retry counter should reset to initial value and start again. Can I achieve this using only Polly or should I write my own logic? Ideas?
Polly has nothing in-built to manage dialog boxes as it is entirely agnostic to the context in which it is used. However, you can customise extra behaviour on retries with an onRetry delegate so you can hook a dialog box in there. Overall:
Use an outer RetryForever policy, and display the dialog box in the onRetry action configured on that policy.
If you want a way for the user to exit the RetryForever, a cancel action in the dialog could throw some other exception (which you trap with a try-catch round all the policies), to cause an exit.
Within the outer policy, use an inner Retry policy for however many tries you want to make without intervention.
Because this is a different policy instance from the retryforever, and has fixed retry count, the retry count will automatically start afresh each time it is executed.
Use PolicyWrap to wrap the two retry policies together.
In pseudo-code:
var retryUntilSucceedsOrUserCancels = Policy
.Handle<WhateverException>()
.RetryForever(onRetry: { /* show my dialog box*/ });
var retryNTimesWithoutUserIntervention = Policy
.Handle<WhateverException>()
.Retry(n); // or whatever more sophisticated retry style you want
var combined = retryUntilSucceedsOrUserCancels
.Wrap(retryNTimesWithoutUserIntervention);
combined.Execute( /* my work */ );
Of course the use of the outer RetryForever() policy is just an option: you could also build the equivalent manually.

Resources