RxSwift throttle() to get first element - swift

I am looking for a way in which the throttle() operator gives up the first element in an Observable within a given time-interval, rather than the last element.
A similar question has been asked (and answered) in RxSwift - Debounce/Throttle "inverse", but there is an imperfection in those answers that I would like to avoid. That is, in an ideal scenario, the first element emitted in the Observable is obtained and any future ones are ignored for the duration of the time-interval. However, when working with window() or timer(), it is possible that two elements proceed within the given time-interval, because the timer happened not to run parallel to the start of the throttle() call. Example:
|..........|..........|..........|
^ ^
first second
They fall into different windows and are therefore both accepted by the imperfect solution described in the linked answer.
Ideally, there would be a way to restart the timer as soon as the first element in a window comes in, so that the above example would instead look something like:
|..........|.......|..........|
^ ^
first second (ignored)
Any ideas?
Edit: to be clear, I am not sure how the throttle() variety of RxSwift 3.0-beta1 handles this, but I am looking for a solution for RxSwift 2.x implementations.

As it turns out, rxSwift 3.0 deals with throttle() in exactly the way I desired. It takes an element and then ignores any further elements for x seconds (without having the 'window problem' I alluded to in the question).
For the sake of completeness: debounce() still works in accordance with rxSwift's 'old' definition of throttling. That is, it takes the last item in a time-interval.

Related

Writing custom QGIS function in Python - is there a difference between "feature" and "$currentfeature"

I wrote the following custom qgsfunction:
#qgsfunction(args='auto', group='Custom', referenced_columns=[])
def f1(currentfeature, feature, parent):
return "%s\n%s" % (repr(currentfeature),repr(feature))
In the config for the label I enter the following expression:
f1($currentfeature)
And here is the result:
I always believed that the $currentfeature would hold the same value as the implicitly passed argument feature, but they appear to be separate objects.
Can someone please either
confirm that they should be the same value, or
explain the difference between the two
(I also experience other odd things when executing my own custom functions, and I suspect something is not behaving as it should. Sometimes the addresss of the object changes when I zoom in or out, the address seems to cycle between af few values, and simply takes the next value in the cycle when I do any kind of zoom action. And the reason why I got to experiment with this in the first place is because I did not get the expected/correct attribute values back)

using transformToUni

being relatively new to mutiny I am having a little difucauly wrapping my head around the following:
given the following working code:
public Uni<Long> getCounterValue() {
return this.vertx.sharedData().getCounter(COUNTER_NAME).onItem().transformToUni(counter->counter.get());
}
I simply want to return a Uni where the Long is a current state of a vert.x shared counter.
what is hard for me is that counter.get() actually already returns a Uni so I feel like I am doing a transformToUni on something that already has the return time I need.
I hope I explained myself. like I said, the code works but its hard for me to get the why... maybe there's also another way, more self explanatory, to achieve this?
(BTW, I looked at the guides but still I am confused)
your comments are appreciated.
thanks
I think the explanation is that you need a new Uni that's aware of the event emitted by getCounter and that will call counter.get(). Or, in general, a new Uni that knows what to do with the result of the previous one and makes sure that everything happens in the right order at subscription.
Let's take a simpler example, we have three Uni:
Uni<?> first = Uni.createFrom,().item(1).invoke(System.out::print);
Uni<?> second = Uni.createFrom().item(2).invoke(System.out::print);
Uni<?> third = first.chain(() -> second);
If you subscribe first, it will print 1.
If you subscribe second, it will print 2.
If you subscribe third, it will print 12.
These are three different Uni, emitting different events at different times.
What you are suggesting is to return second when transformToUni (or chain) is called to create third. But, in that case, the result would be different from what we want.

Passing Args Down Catalyst Chain w/$c->visit

In one of my Catalyst actions, I'm trying to go off and get the body response (HTML) of another action in a different controller. (For the purpose of sort of "embedding" one page in another)
I figured the way to do this was a $c->visit. (If I misunderstood $c->visit, then the rest of my question need not be answered.)
The action in question takes an arg, but not until further down the chain, which looks like this:
/equipment/*/assets/widget
/assets/captureID (1)
-> /assets/base (0)
-> /assets/pageData (0)
=> /assets/widget
As you can see, only the last action in the chain is looking for an arg.
If I try:
$c->visit('/assets/widget',[$arg]);
I would expect it to travel down the chain and give /assets/captureID my $arg. But in fact, it doesn't seem to get passed down the chain at all.
Where have I gone astray?
As you've discovered, the body doesn't exist at that point. You'd have to have made a call to render your view, or make an arrangement for /assets/widget to set $c->res->body($foo) directly. I find the idea of capturing the body of a sub-request unconventional, to put it mildly. I can't imagine what you are going to do with it that isn't going to go against the principles of good MVC design.
It sounds to me like the logic that is in /assets/widget needs to be located in the Model rather than the Controller, so that it can be used by whatever function requires it.
And/or you need to break your templates down into (reusable) components, so that whatever content you planned to embed could be done as part of a single rendering process.
[%- IF foo;
PROCESS widget.tt;
END; -%]
Turns out only the captures, not the args get passed down the chain.
According to the doc:
$c->visit( $action [, \#captures, \#arguments ] )
So I was able to have success by doing the following:
$c->visit('/assets/widget',[$arg],[$arg])
The first array of args hits the first action and stops, but the second array travels all the way down the chain like I wanted.
I expected $c->visit('/assets/widget',[],[$arg]) to work, but it does not.
However, after all that I realized I can't just grab the body response that way, which was the ultimate goal. Either way, hopefully my goose chase was helpful to someone.

Implementing snapshot in FRP

I'm implementing an FRP framework in Scala and I seem to have run into a problem. Motivated by some thinking, this question I decided to restrict the public interface of my framework so Behaviours could only be evaluated in the 'present' i.e.:
behaviour.at(now)
This also falls in line with Conal's assumption in the Fran paper that Behaviours are only ever evaluated/sampled at increasing times. It does restrict transformations on Behaviours but otherwise we find ourselves in huge problems with Behaviours that represent some input:
val slider = Stepper(0, sliderChangeEvent)
With this Behaviour, evaluating future values would be incorrect and evaluating past values would require an unbounded amount of memory (all occurrences used in the 'slider' event would have to be stored).
I am having trouble with the specification for the 'snapshot' operation on Behaviours given this restriction. My problem is best explained with an example (using the slider mentioned above):
val event = mouseB // an event that occurs when the mouse is pressed
val sampler = slider.snapshot(event)
val stepper = Stepper(0, sampler)
My problem here is that if the 'mouseB' Event has occurred when this code is executed then the current value of 'stepper' will be the last 'sample' of 'slider' (the value at the time the last occurrence occurred). If the time of the last occurrence is in the past then we will consequently end up evaluating 'slider' using a past time which breaks the rule set above (and your original assumption). I can see a couple of ways to solve this:
We 'record' the past (keep hold of all past occurrences in an Event) allowing evaluation of Behaviours with past times (using an unbounded amount of memory)
We modify 'snapshot' to take a time argument ("sample after this time") and enforce that that time >= now
In a more wacky move, we could restrict creation of FRP objects to the initial setup of a program somehow and only start processing events/input after this setup is complete
I could also simply not implement 'sample' or remove 'stepper'/'switcher' (but I don't really want to do either of these things). Has anyone any thoughts on this? Have I misunderstood anything here?
Oh I see what you mean now.
Your "you can only sample at 'now'" restriction isn't tight enough, I think. It needs to be a bit stronger to avoid looking into the past. Since you are using an environmental conception of now, I would define the behavior construction functions in terms of it (so long as now cannot advance by the mere execution of definitions, which, per my last answer, would get messy). For example:
Stepper(i,e) is a behavior with the value i in the interval [now,e1] (where e1 is the
time of first occurrence of e after now), and the value of the most recent occurrence of e afterward.
With this semantics, your prediction about the value of stepper that got you into this conundrum is dismantled, and the stepper will now have the value 0. I don't know whether this semantics is desirable to you, but it seems natural enough to me.
From what I can tell, you are worried about a race condition: what happens if an event occurs while the code is executing.
Purely functional code does not like to have to know that it gets executed. Functional techniques are at their finest in the pure setting, such that it does not matter in what order code is executed. A way out of this dilemma is to pretend that every change happened in one sensitive (internal, probably) piece of imperative code; pretend that any functional declarations in the FRP framework happen in 0 time so it is impossible for something to change during their declaration.
Nobody should ever sleep, or really do anything time sensitive, in a section of code that is declaring behaviors and things. Essentially, code that works with FRP objects ought to be pure, then you don't have any problems.
This does not necessarily preclude running it on multiple threads, but to support that you might need to reorganize your internal representations. Welcome to the world of FRP library implementation -- I suspect your internal representation will fluctuate many times during this process. :-)
I'm confused about your confusion. The way I see is that Stepper will "set" the behavior to a new value whenever the event occurs. So, what happens is the following:
The instant in which the event mouseB occurs, the value of the slider behavior will be read (snapshot). This value will be "set" into the behavior stepper.
So, it is true that the Stepper will "remember" values from the past; the point is that it only remembers the latest value from the past, not everything.
Semantically, it is best to model Stepper as a function like luqui proposes.

What do the various ISubject implementations do and when would they be used?

I have a fairly good idea of what the Subject class does and when to use it, but I've just been looking through the language reference on msdn and see there are various other ISubject implementations such as:
AsyncSubject
BehaviorSubject
ReplaySubject
As the documentation is pretty thin on the ground, whats the point of each of these types and under what situations would you use them?
These subjects all share a common property - they take some (or all) of what gets posted to them via OnNext and record it and play it back to you - i.e. they take a Hot Observable and make it Cold. This means, that if you Subscribe to any of these more than once (i.e. Subscribe => Unsubscribe => Subscribe again), you'll see at least one of the same value again.
ReplaySubject: Every time you subscribe to the Subject, you get the entire history of what has been posted replayed back to you, as fast as possible (or a subset, like the last n items)
AsyncSubject: Always plays back the last item posted and completes, but only after the source has completed. This Subject is awesome for async functions, since you can write them without worrying about race conditions: even if someone Subscribes after the async method completes, they get the result.
BehaviorSubject: Kind of like ReplaySubject but with a buffer of one, so you always get the last thing that was posted. You also can provide an initial value. Always provides one item instantly on Subscribe.
In light of the latest version (v1.0.2856.0) and to keep this question up to date, there has been a new set of subject classes:
FastSubject, FastBehaviorSubject, FastAsyncSubject and FastReplaySubject
As per the release notes they
are much faster than regular subjects
but:
don’t decouple producer and consumer by an IScheduler
(effectively limiting them to
ImmediateScheduler);
don’t protect against stack overflow;
don’t synchronize input messages.
Fast subjects are used by Publish and
Prune operators if no scheduler is
specified.
In regards to AsyncSubject
This code:
var s = new AsyncSubject<int>();
s.OnNext(1);
s.Subscribe(Console.WriteLine);
s.OnNext(2);
s.OnNext(3);
s.OnCompleted();
prints a single value 3. And it prints same if subscription is moved to after completion. So it plays back not the first, but the last item, plays it after completion (until complete, it does not produce values), and it does not work like Subject before completion.
See this Prune discussion for more info (AsyncSubject is basically the same as Prune)
Paul's answer pretty much nails it. There's a few things worth adding, though:
AsyncSubject works as Paul says, but only after the source completes. Before that, it works like Subject (where "live" values are received by subscribers)
AsyncSubject has changed since I last ran tests against it. It no longer acts as a live subject before completion, but waits for completion before it emits a value. And, as Sergey mentions, it returns the last value, not the first (though I should have caught that as that's always been the case)
AsyncSubject is used by Prune, FromAsyncPattern, ToAsync and probably a few others
BehaviorSubject is used by overloads of Publish that accept an initial value
ReplaySubject is used by Replay
NOTE: All operator references above refer to the publishing set of operators as they were before they were replaced with generalised publish operators in rev 2838 (Christmas '10) as it has been mentioned that the original operators will be re-added