Reactive Extensions (UI) increasing event calls - system.reactive

I have the below code.
this.ObservableForProperty(x => x.SelectedDay)
.Throttle(TimeSpan.FromMilliseconds(3600))
.Where(x => SelectedDay != null)
.ObserveOn(CoreWindow.GetForCurrentThread().Dispatcher)
.Subscribe(x => SomeRandomMethod());
Throttle is working great and it will not call SomeRandomMethod until x.SelectedDay has stopped changing. However it is calling it for each time that it has changed.
So i do this:
Change,
Change,
Wait
//SomeRandomMethod called 2 times at end of throttle
Change
Wait
//SomeRandomMethod called 3 times
Change
Change
Change
Wait
//SomeRandomMethod called 6 times.
How can i get it to ignore all previous change events and only get the latest at the time throttle has done it's thing.
So i would like this:
Change
Change
Wait
//SomeRandomMethod called once
Change
Wait
//SomeRandomMethod called once
Change
Change
Change
Wait
//SomeRandomMethod called once

Where are you calling this method? You should only be calling it in the Constructor, and only calling it once. Also, here's a better version of the code above:
this.ObservableForProperty(x => x.SelectedDay)
.Throttle(TimeSpan.FromMilliseconds(3600), RxApp.DeferredScheduler)
.Where(x => SelectedDay != null)
.Subscribe(x => SomeRandomMethod());

Related

Is it possible to dynamically update if functions in anylogic?

I'm using a state chart in combination with a schedule in Anylogic (see picture). The output of the schedule is equal to 1 during working hours and 0 otherwise. Now I want the transition from state1 to state2 to happen when the schedule is turning to 1 or is equal to 1(so otherwise wait until the working hours).
I have tried using an if statement
if( main.plannerSchedule()==1 )(<perform action>)
However, by this method, the state transition only happens if the statement is true but doesn't wait for it to become true. Is there a way to constantly update the state transition or is there a "wait until" function that can solve this problem?
Best let the schedule send a message to your statechart when it switches. This assumes that the statechart lives on the same agent type as the schedule. Write this code in the action code box of the schedule:
if (value==1) {
statechart.fireEvent("go to state 2");
}
Obviously, your message transition needs to await the "go to state 2" message.
Note the value keyword. See https://www.benjamin-schumann.com/blog/2016/2/4/the-magic-lightbulb-and-how-it-can-help-your-anylogic-modelling for more info on that

How to trigger handle_info due to timeout in erlang?

I am using a gen_server behaviour and trying to understand how can handle_info/2 be triggered from a timeout occurring in a handle_call for example:
-module(server).
-export([init/1,handle_call/3,handle_info/2,terminate/2).
-export([start/0,stop/0]).
init(Data)->
{ok,33}.
start()->
gen_server:start_link(?MODULE,?MODULE,[]).
stop(Pid)->
gen_server:stop(Pid).
handle_call(Request,From,State)->
Return={reply,State,State,5000},
Return.
handle_info(Request,State)->
{stop,Reason,State}.
terminate(Reason,State)->
{ok,S}=file:file_open("D:/Erlang/Supervisor/err.txt",[read,write]),
io:format(S,"~s~n",[Reason]),
ok.
What i want to do:
I was expecting that if I launch the server and would not use gen_server:call/2 for 5 seconds (in my case) then handle_info would be called, which would in turn issue the stop thus calling terminate.
I see it does not happen this way, in fact handle_info is not called at all.
In examples such as this i see the timeout is set in the return of init/1.What I can deduce is that it handle_info gets triggered only if I initialize the server and issue nothing (nor cast nor call for N seconds).If so why I can provide Timeout in the return of both handle_cast/2 and handle_call/3 ?
Update:
I was trying to get the following functionality:
If no call is issued in X seconds trigger handle_info/2
If no cast is issued in Y seconds trigger handle_info/2
I thought this timeouts can be set in the return of handle_call and handle_cast:
{reply,Reply,State,X} //for call
{noreply,State,Y} //for cast
If not, when are those timeouts triggered since they are returns?
To initiate timeout handling from gen_server:handle_call/3 callback, this callback has to be called in the first place. Your Return={reply,State,State,5000}, is not executed at all.
Instead, if you want to “launch the server and would not use gen_server:call/2 for 5 seconds then handle_info/2 would be called”, you might return {ok,State,Timeout} tuple from gen_server:init/1 callback.
init(Data)->
{ok,33,5000}.
You cannot set the different timeouts for different calls and casts. As stated by Alexey Romanov in comments,
Having different timeouts for different types of messages just isn’t something any gen_* behavior does and would have to be simulated by maintaining them inside state.
If one returns {reply,State,Timeout} tuple from any handle_call/3/handle_cast/2, the timeout will be triggered if the mailbox of this process is empty after Timeout.
i suggest you read source code:gen_server.erl
% gen_server.erl
% line 400
loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug) ->
Msg = receive
Input ->
Input
after Time ->
timeout
end,
decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, false).
it helps you to understand the parameter Timeout

Why is the Streamlistener reacting differently?

I'm trying to use the Streambuilder in cooperation with Bloc. The problem is that somehow the UI updates only when the expensive Funktions are finished. It seems that then, and only then updates are made to the stream. But I can not figure out why?
I Implemented a simple Bloc that has 4 events:
1. a Future called over the Bloc Sate Object
2. a Future called inside the Bloc
3. a Funktion called inside the Bloc
4 just using Future.delay
I'm Trying to understand why everything behaves as expectetd, but not when I use first two. My guess is I have a basic misunderstanding of the eventloop but I can not see why there should be a difference in behavior between 2 and 4 or 1 and 4
To make it easy I made an example Project on Github
https://github.com/pekretsc/bloceventloop.git
So I have my refresh methode that ads the new state to the Stream.
if (event is ExpensiveEventInState) {
refresh(BlocUIState.Waiting);
String result = await blocState.doSomeThing();
if (result == '') {
refresh(BlocUIState.Fin);
} else {
refresh(BlocUIState.Fail);
}
}
if (event is ExpensiveEventWhyDoesThisWork) {
refresh(BlocUIState.Waiting);
await Future.delayed(Duration(seconds: 3));
refresh(BlocUIState.Fin);
}
so the question is, should the first and second event not behave the same way?
What happens though is that in the first case the refresh is ignored completely and just the Fin is added to the stream. (I checked that, its not that it is too fast to recognize)
StreamListener's callback is called immediately when an event is pushed on the stream.
On the other hand, StreamBuilder's builder callback isn't. For most common use-cases, it is called at most once per frame.

mapbox styledata event fire 3 times, I only need fire 1 time, how?

mapbox styledata event fire 3 times, I only need fire 1 time, how?
map.on("styledata", loadTiles); // will fire multiple 3 times, whenever style changed.
// event.stopPropagation(); does not work.
map.on("load", loadTiles); // only fire 1 time. but when you change base map, use below
map.setStyle('mapbox://styles/mapbox/' + layerId, {diff: false});
// on load event will not fire, which I need it fire to re-load geojson layer.
map.on("styledata" // works fine, but it fire 3 same event at same time, cause load 3 times geojson layer, cause other error when you load 3 times geojson layer at same time.
// How to make styledata on fire 1 times instead of 3?
Found the following combination of events to be useful to only fire 1 instead of 3 styledata event :
map.on('styledataloading', function() {
console.log('A styledataloading event occurred.');
map.once('styledata', function() {
console.log('A styledata event occurred.');
loadTiles();
});
});
Explanation:
The first event (styledataloading) fires when the map's style starts to change.
styledataloading: Fired when the map's style begins loading or changing asyncronously. All styledataloading events are followed by a styledata or error event.
As callback you can set up an event listener that only fires for the first styldata event using the map.once(...).
Once: Adds a listener that will be called only once to a specified event type.
The listener will be called first time the event fires after the listener is registered.
This way you don't loose the event listener for stylechanges after the first change as you would if you just use map.once('styledata', loadTiles);.
The answer in 2019 is:
map.once('styledata', loadTiles); //The listener will be called first time the event fires after the listener is registered.
map.once('styledata', loadTiles); //The listener will be called first time the event fires after the listener is registered.
map.on("styledata", loadTiles); // will fire multiple 3 times, whenever style changed.
// event.stopPropagation(); does not work.
map.on("load", loadTiles); // only fire 1 time. but when you change base map, use below
map.setStyle('mapbox://styles/mapbox/' + layerId, {diff: false});
// on load event will not fire, which I need it fire to re-load geojson layer.
map.on("styledata" // works fine, but it fire 3 same event at same time, cause load 3 times geojson layer, cause other error when you load 3 times geojson layer at same time.

Offer to queue with some initial display

I want to offer to queue a string sent in load request after some initial delay say 10 seconds.
If the subsequent request is made with some short interval delay(1 second) then everything works fine, but if it is made continuously like from a script then there is no delay.
Here is the sample code.
def load(randomStr :String) = Action { implicit request =>
Source.single(randomStr)
.delay(10 seconds, DelayOverflowStrategy.backpressure)
.map(x =>{
println(x)
queue.offer(x)
})
.runWith(Sink.ignore)
Ok("")
}
I am not entirely sure that this is the correct way of doing what you want. There are some things you need to reconsider:
a delayed source has an initial buffer capacity of 16 elements. You can increase this with addAttributes(initialBuffer)
In your case the buffer cannot actually become full because every time you provide just one element.
Who is the caller of the Action? You are defining a DelayOverflowStrategy.backpressure strategy but is the caller able to handle this?
On every call of the action you are creating a Stream consisting of one element, how is the backpressure here helping? It is applied on the stream processing and not on the offering to the queue