Foreword Introduction 1. Reactive Programming with RxJava Reactive Programming and RxJava When You Need Reactive Programming How RxJava Works Push versus Pull Async versus Sync Concurrency and Parallelism Lazy versus Eager Duality Cardinality Mechanical Sympathy: Blocking versus Nonblocking I/O Reactive Abstraction
2. Reactive Extensions Anatomy of rx.Observable Subscribing to Notifications from Observable Capturing All Notifications by Using Observer Controlling Listeners by Using Subscription and Subscriber Creating Observables Mastering Observable.create0 Infinite Streams Timing: timer() and interval() Hot and Cold Observables Use Case: From Callback API to Observable Stream Manually Managing Subscribers rx.subjects.Subject ConnectableObservable Single Subscription with publishO.refCountO ConnectableObservable Lifecycle Summary
3. Operators and Transformations Core Operators: Mapping and Filtering 1-to-1 Transformations Using map() Wrapping Up Using flatMap0 Postponing Events Using the delay() Operator Order of Events After flatMap0 Preserving Order Using concatMap0 More Than One Observable Treating Several Observables as One Using merge() Pairwise Composing Using zip() and zipWith() When Streams Are Not Synchronized with One Another: combineLatest(), withLatestFrom(), and amb() Advanced Operators: collect(), reduce(), scan(), distinct(), and groupBy() Scanning Through the Sequence with Scan and Reduce Reduction with Mutable Accumulator: collect() Asserting Observable Has Exactly One Item Using single() Dropping Duplicates Using distinct() and distinctUntilChanged() Slicing and Dicing Using skip(), takeWhile(), and Others Ways of Combining Streams: concat(), merge(), and switchOnNext() Criteria-Based Splitting of Stream Using groupBy0 Where to Go from Here? Writing Customer Operators Reusing Operators Using compose() Implementing Advanced Operators Using lift() Summary
4. Applying Reactive Programming to Existing Applications From Collections to Observables BlockingObservable: Exiting the Reactive World Embracing Laziness Composing Observables Lazy paging and concatenation Imperative Concurrency flatMap0 as Asynchronous Chaining Operator Replacing Callbacks with Streams Polling Periodically for Changes Multithreading in RxJava What Is a Scheduler? Declarative Subscription with subscribeOn() subscribeOn0 Concurrency and Behavior Batching Requests Using groupBy() Declarative Concurrency with observeOn() Other Uses for Schedulers Summary
5. Reactive from Top to Bottom Beating the C1Ok Problem Traditional Thread-Based HTTP Servers Nonblocking HTTP Server with Netty and RxNetty Benchmarking Blocking versus Reactive Server Reactive HTTP Servers Tour HTTP Client Code Nonblocking HTTP Client with RxNetty Relational Database Access NOTIFY AND LISTEN on PostgreSQL Case Study CompletableFuture and Streams A Short Introduction to CompletableFuture Interoperability with CompletableFuture Observable versus Single Creating and Consuming Single Combining Responses Using zip, merge, and concat Interoperability with Observable and CompletableFuture When to Use Single? Summary
6. Flow Control and Backpressure Flow Control Taking Periodic Samples and Throttling Buffering Events to a List Moving window Skipping Stale Events by Using debounce() Backpressure Backpressure in RxJava Built-in Backpressure Producers and Missing Backpressure Honoring the Requested Amount of Data Summary
7. Testing and Troubleshooting Error Handling Where Are My Exceptions? Declarative try-catch Replacement Timing Out When Events Do Not Occur Retrying After Failures Testing and Debugging Virtual Time Schedulers in Unit Testing Unit Testing Monitoring and Debugging doOn...() Callbacks Measuring and Monitoring Summary
8. Case Studies Android Development with RxJava Avoiding Memory Leaks in Activities Retrofit with Native RxJava Support Schedulers in Android UI Events as Streams Managing Failures with Hystrix The First Steps with Hystrix Nonblocking Commands with HystrixObservableCommand Bulkhead Pattern and Fail-Fast Batching and Collapsing Commands Monitoring and Dashboards Querying NoSQL Databases Couchbase Client API MongoDB Client API Camel Integration Consuming Files with Camel Receiving Messages from Kafka Java 8 Streams and CompletableFuture Usefulness of Parallel Streams Choosing the Appropriate Concurrency Abstraction When to Choose Observable? Memory Consumption and Leaks Operators Consuming Uncontrolled Amounts of Memory Summary
9. Future Directions Reactive Streams Observable and Flowable Performance Migration A. More HTTP Server Examples B. A Decision Tree of Observable Operators Index
精彩書摘
《RxJava反應式編程(影印版 英文版)》: You will not see similar low-level implementations outside of the university, but itworks.For each request we ignore whatever was sent to us and return 2000Kresponses.Opening localhost:8080 in the browser succeeds with an OK text reply.The class is named SingleThread for a reason.Serversocket.accept() blocks untilany client establishes a connection with us.Then, it returns a client Socket.While weinteract with that Socket (read and write to it), we still listen for incoming connec-tions but no one picks them up because our thread is busy handling first client.It islike at the doctor's office: one patient goes in and everyone else must wait in a queue.Did you notice the extra 100 parameter after 8080 (listening port)? This value (thedefault is 50) caps the maximum number of pending connections that can wait in aqueue.Above that number, they are rejected.To make matters worse, we pretend toimplement HTTP/1.1 which uses persistent connections by default.Until the clientdisconnects we keep the TCP/IP connection open just in case, blocking new clients. ……