rx-java


Implementing a rate limited search results using `Observable`s


Let's say I have two Observables:
obs1 emits results of user input in a search box,
obs2 takes a string as an input and initiates an HTTP request, then provides a result
Now, I want to limit the number of HTTP requests not by some constant time interval but depending on when an obs2 is done with a current request, something like this:
User types t, obs2 immediately starts a request with t
User types te, obs2 is still "busy", nothing happens
User types tes, obs2 is still "busy", nothing happens
User types test, obs2 is still "busy", nothing happens
t-HTTP response has arrived, obs2 is now "free", it looks at obs1 last emitted value and finds test, starts a new request
test-HTTP response has arrived, obs2 is now "free", it looks at obs1 last emitted value and finds test, does nothing because the value has not changed.
I could do this by introducing additional variables which would indicate a state of the system and a search query accumulator but I wonder if this could be done in purely functional way i.e. by using rxJava methods alone?
See code and comment.
import rx.Observable;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
import xdean.jex.extra.Pair;
public class Q43975663 {
public static void main(String[] args) throws InterruptedException {
PublishSubject<String> textSub = PublishSubject.create(); // emit user input text
PublishSubject<String> taskSub = PublishSubject.create(); // emit when execution thread is free
// core
Observable
// when new text input or execution thread change to free, emit an item
.combineLatest(textSub.distinctUntilChanged(), taskSub, Pair::of)
// if the text not change or task cycle not change, ignore it
.scan((p1, p2) ->
(p1.getLeft().equals(p2.getLeft()) || p1.getRight().equals(p2.getRight())) ?
p1 : p2)
.distinctUntilChanged()
// map to user input text
.map(Pair::getLeft)
// scheduler to IO thread
.observeOn(Schedulers.io())
// do HTTP request
.doOnNext(Q43975663::httpTask)
// emit item to notify the execution thread is free
.doOnNext(taskSub::onNext)
.subscribe();
// test
taskSub.onNext("start");
textSub.onNext("t");
textSub.onNext("te");
textSub.onNext("tex");
textSub.onNext("text");
Thread.sleep(5000);
textSub.onNext("new");
textSub.onNext("new");
textSub.onNext("text");
Thread.sleep(5000);
}
static void httpTask(String id) {
System.out.printf("%s \tstart on \t%s\n", id, Thread.currentThread());
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s \tdone on \t%s\n", id, Thread.currentThread());
}
}
Note Pair is a simple class with two values, left and right.
output:
t start on Thread[RxIoScheduler-2,5,main]
t done on Thread[RxIoScheduler-2,5,main]
text start on Thread[RxIoScheduler-2,5,main]
text done on Thread[RxIoScheduler-2,5,main]
new start on Thread[RxIoScheduler-2,5,main]
new done on Thread[RxIoScheduler-2,5,main]
text start on Thread[RxIoScheduler-2,5,main]
text done on Thread[RxIoScheduler-2,5,main]

Related Links

RxAndroid: Where is ReactiveDialog?
Process Observable on background thread
AsyncTask replacement with RXJava help needed
Transform children objects to parent object, grouped by parent
Start emiting values after custom event
vertx rx.Observable.subscribe to return input stream
Cancelling an Observable in RxJava
Executing Observables in sequence
Chaining Independent Observables
RxJava Subject not repeating with .repeat()?
Debounce only false values in boolean observable
Sequence of Retrofits' request where next request depends on result of previous request
just() doesn't work in subscription and flatmap()
Rx - Reducing a list of numbers to a series of (number,count)
Using one Observable to clock another Observable
Does join operator in RxJava allow specifying windows by count?

Categories

HOME
neural-network
slickgrid
phpunit
environment-variables
kotlin
google-speech-api
winzip
cakephp-3.0
aws-codepipeline
wlan
mips32
unity5
asp.net-web-api2
ejb
crc32
jspdf
boost-intrusive
treeset
angularjs-ng-route
photon
axon
firebreath
j
laravel-blade
netbeans-7.3
mitmproxy
gun
fgets
swtbot
file-permissions
react-apollo
xfce
boost-python
preview
ctype
interceptor
hal
mahapps.metro
jquery-ui-autocomplete
ipc
inorder
uppercase
aspose-cells
yamldotnet
nestedscrollview
product-key
google-optimize
nerdtree
scalacheck
qnx
autocorrect
react-d3
strconv
knockout-validation
bisonc++
bubble-sort
apple-search-ads
hasownproperty
dde
parrot
powergrep
ratchet
java-threads
simplify
f#-interactive
anonymity
mongoose-web-server
r1soft
jseparator
ti-nspire
visual-studio-2010-sp1
voog
ironscheme
compiler-options
chap-links-library
tbb
runscope
controltemplate
apparmor
string-conversion
declarative-services
android-x86
kendo-validator
activator
stockquotes
styledtext
topcoat
android-3.0-honeycomb
tiles2
rounded-corners
circular-reference
objectiveflickr
incompatibletypeerror
ctime
osx-gatekeeper
nsformatter
plcrashreporter
windows-networking
css-parsing
ant4eclipse
validationsummary
application-design
xla

Resources

Encrypt Message



code
soft
python
ios
c
html
jquery
cloud
mobile