Reactive Programming with RxJava for Efficient Data Access
-
Upload
couchbase -
Category
Data & Analytics
-
view
1.714 -
download
1
description
Transcript of Reactive Programming with RxJava for Efficient Data Access
![Page 1: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/1.jpg)
Reactive Programming with RxJavafor Efficient Data Access
Ben Christensen | Software Engineer, Netflix
Michael Nitschinger | Software Engineer, Couchbase
![Page 2: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/2.jpg)
RxJava
Reactive Extensions for Async Programming
![Page 3: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/3.jpg)
Reactive Extensions for Async Programming
RxJavahttp://github.com/ReactiveX/RxJavahttp://reactivex.io
Single Multiple
Sync T getData() Iterable<T> getData()
Async Future<T> getData() Observable<T> getData()
![Page 4: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/4.jpg)
Single Multiple
Sync T getData() Iterable<T> getData()
Async Future<T> getData() Observable<T> getData()
Observable.create(subscriber -> { subscriber.onNext("Hello world!"); subscriber.onCompleted();}).forEach(System.out::println);
Synchronoussingle value
![Page 5: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/5.jpg)
Single Multiple
Sync T getData() Iterable<T> getData()
Async Future<T> getData() Observable<T> getData()
Observable.create(subscriber -> { subscriber.onNext("Hello"); subscriber.onNext("world"); subscriber.onNext("!"); subscriber.onCompleted();}).forEach(System.out::println);
Synchronousmulti-value
![Page 6: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/6.jpg)
Single Multiple
Sync T getData() Iterable<T> getData()
Async Future<T> getData() Observable<T> getData()
Observable.create(subscriber -> { try { subscriber.onNext(doSomething()); subscriber.onCompleted(); } catch (Throwable e) { subscriber.onError(e); }}).subscribeOn(Schedulers.io()) .forEach(System.out::println);
Asynchronoussingle valuewith error handling
![Page 7: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/7.jpg)
Single Multiple
Sync T getData() Iterable<T> getData()
Async Future<T> getData() Observable<T> getData()
Observable.create(subscriber -> { int i = 0; while (!subscriber.isUnsubscribed()) { subscriber.onNext(i++); }}).take(10).forEach(System.out::println);
Synchronousmulti-valuewith unsubscribe
![Page 8: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/8.jpg)
Single Multiple
Sync T getData() Iterable<T> getData()
Async Future<T> getData() Observable<T> getData()
Observable.create(subscriber -> { AtomicInteger i = new AtomicInteger(); AtomicLong requested = new AtomicLong(); subscriber.setProducer(r -> { if (requested.getAndAdd(r) == 0) { do { if (subscriber.isUnsubscribed()) { break; } subscriber.onNext(i.incrementAndGet()); } while (requested.decrementAndGet() > 0); } });}).observeOn(Schedulers.newThread()) .take(10).forEach(System.out::println);
Synchronous multi-valued source that thread-hopswith “reactive pull” backpressure
![Page 9: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/9.jpg)
Single Multiple
Sync T getData() Iterable<T> getData()
Async Future<T> getData() Observable<T> getData()
Observable.from(iterable) .observeOn(Schedulers.newThread()) .take(10).forEach(System.out::println);
Synchronous multi-valued source that thread-hopswith “reactive pull” backpressure
![Page 10: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/10.jpg)
![Page 11: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/11.jpg)
![Page 12: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/12.jpg)
![Page 13: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/13.jpg)
13
Abstract Concurrency
©2014 Couchbase, Inc. — Proprietary and Confidential
![Page 14: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/14.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 15: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/15.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 16: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/16.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 17: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/17.jpg)
Observable<R> b = Observable<T>.flatMap({ T t -> Observable<R> r = ... transform t ... return r; })
flatMap
![Page 18: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/18.jpg)
Observable<R> b = Observable<T>.flatMap({ T t -> Observable<R> r = ... transform t ... return r; })
flatMap
![Page 19: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/19.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 20: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/20.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 21: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/21.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 22: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/22.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 23: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/23.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 24: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/24.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 25: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/25.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 26: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/26.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 27: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/27.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 28: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/28.jpg)
Observable.zip(a, b, { a, b, -> ... operate on values from both a & b ... return [a, b]; // i.e. return tuple })
![Page 29: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/29.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 30: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/30.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 31: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/31.jpg)
![Page 32: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/32.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 33: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/33.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 34: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/34.jpg)
class VideoService { def VideoList getPersonalizedListOfMovies(userId); def VideoBookmark getBookmark(userId, videoId); def VideoRating getRating(userId, videoId); def VideoMetadata getMetadata(videoId);}
class VideoService { def Observable<VideoList> getPersonalizedListOfMovies(userId); def Observable<VideoBookmark> getBookmark(userId, videoId); def Observable<VideoRating> getRating(userId, videoId); def Observable<VideoMetadata> getMetadata(videoId);}
... create an observable api:
instead of a blocking api ...
![Page 35: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/35.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
1
2
34
5
6
![Page 36: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/36.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
1
2
34
5
6
![Page 37: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/37.jpg)
37
Non-Opinionated Concurrency
©2014 Couchbase, Inc. — Proprietary and Confidential
![Page 38: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/38.jpg)
![Page 39: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/39.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
![Page 40: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/40.jpg)
![Page 41: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/41.jpg)
![Page 42: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/42.jpg)
![Page 43: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/43.jpg)
![Page 44: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/44.jpg)
public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) { // first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); }).flatMap(data -> { // output as SSE as we get back the data (no waiting until all is done) return response.writeAndFlush(new ServerSentEvent(SimpleJson.mapToJson(data))); });}
1
2
34
6
![Page 45: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/45.jpg)
![Page 46: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/46.jpg)
// first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); })
Decouples Consumption from Production
![Page 47: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/47.jpg)
// first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); })
Decouples Consumption from Production
![Page 48: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/48.jpg)
// first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); })
Decouples Consumption from Production
![Page 49: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/49.jpg)
Decouples Consumption from Production
![Page 50: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/50.jpg)
Decouples Consumption from Production
// first request User object return new UserCommand(request.getQueryParameters().get("userId")).observe().flatMap(user -> { // then fetch personal catalog Observable<Map<String, Object>> catalog = new PersonalizedCatalogCommand(user).observe() .flatMap(catalogList -> { return catalogList.videos().<Map<String, Object>> flatMap(video -> { Observable<Bookmark> bookmark = new BookmarkCommand(video).observe(); Observable<Rating> rating = new RatingsCommand(video).observe(); Observable<VideoMetadata> metadata = new VideoMetadataCommand(video).observe(); return Observable.zip(bookmark, rating, metadata, (b, r, m) -> { return combineVideoData(video, b, r, m); }); }); }); // and fetch social data in parallel Observable<Map<String, Object>> social = new SocialCommand(user).observe().map(s -> { return s.getDataAsMap(); }); // merge the results return Observable.merge(catalog, social); })
1
2
34
5
![Page 51: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/51.jpg)
class VideoService { def Observable<VideoList> getPersonalizedListOfMovies(userId); def Observable<VideoBookmark> getBookmark(userId, videoId); def Observable<VideoRating> getRating(userId, videoId); def Observable<VideoMetadata> getMetadata(videoId);}
Clear API Communicates Potential Cost
![Page 52: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/52.jpg)
Implementation Can Differ
class VideoService { def Observable<VideoList> getPersonalizedListOfMovies(userId); def Observable<VideoBookmark> getBookmark(userId, videoId); def Observable<VideoRating> getRating(userId, videoId); def Observable<VideoMetadata> getMetadata(videoId);}
BIO Network Call
Local Cache CollapsedNetwork Call
![Page 53: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/53.jpg)
class VideoService { def Observable<VideoList> getPersonalizedListOfMovies(userId); def Observable<VideoBookmark> getBookmark(userId, videoId); def Observable<VideoRating> getRating(userId, videoId); def Observable<VideoMetadata> getMetadata(videoId);}
CollapsedNetwork CallCollapsed
Network Call
BIO NIO Network Call
Local Cache
Implementation Can Differ and Change
![Page 54: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/54.jpg)
Retrieval, Transformation, Combination all done in same
declarative manner
![Page 55: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/55.jpg)
Couchbase Java Client 2.0
Reactive from top to bottom
![Page 56: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/56.jpg)
56
Java SDK 2.0
©2014 Couchbase, Inc. — Proprietary and Confidential
It is a complete rewrite compared to 1.* and provides asynchronous & synchronous document oriented APIs.
![Page 57: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/57.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 57
Couchbase Core IO
Common infrastructure & feature set for all language bindings Message oriented Asynchronous only Low overhead and performance focused Supports Java 6+ (including 8!)
Disruptor RingBuffer for implicit batching and backpressure Netty for high performance IO
![Page 58: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/58.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 58
The Big Picture
![Page 59: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/59.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 59
Connecting
![Page 60: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/60.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 60
From Sync to Async
![Page 61: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/61.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 61
Connecting Async
![Page 62: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/62.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 62
Storing a Document
![Page 63: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/63.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 63
Loading a Document
![Page 64: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/64.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 64
Querying
![Page 65: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/65.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 65
Querying
![Page 66: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/66.jpg)
Stability Patterns
![Page 67: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/67.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 67
Reacting to Failure
Resiliency is key Things will go wrong, so better plan for it Do not aim for QA, aim for production
Do not trust integration points Treat the Database (SDK) as an integration point
The more you sweat in peace, the less you bleed in war.
![Page 68: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/68.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 68
Useful Reading
Release It! by Michael T. Nygard
Stability Patterns & Antipatterns Capacity planning Operations
![Page 69: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/69.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 69
Timeouts
The network is unreliable Servers fail The SDK contains bugs
Always specify timeouts and deal with them! The synchronous wrapper defines them for you all the time.
![Page 70: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/70.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 70
Timeouts: Simple
![Page 71: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/71.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 71
Timeouts: Synchronous API
![Page 72: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/72.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 72
Timeouts: Complex Example
![Page 73: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/73.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 73
Coordinated Retry
Fail fast
Don’t let your system get stuck Fail and backpressure
Retry
immediately won’t help either linear or exponential backoff necessary have a strategy if retry also doesn’t work (Fallbacks!)
![Page 74: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/74.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 74
Coordinated Retry: Fallback
![Page 75: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/75.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 75
Coordinated Retry with Delay
![Page 76: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/76.jpg)
©2014 Couchbase, Inc. — Proprietary and Confidential 76
More Patterns
Circuit Breaker
Closed if everything okay Opens once the integration point breaks Fail fast if open Rechecking with half-open
Bulkheads
Isolate failure where possible Don’t let your ship sink!
![Page 77: Reactive Programming with RxJava for Efficient Data Access](https://reader038.fdocuments.in/reader038/viewer/2022102815/557d584ed8b42aba3d8b4925/html5/thumbnails/77.jpg)
QA
Thanks!