Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Tim Ward

tim.ward@paremus.com
Reactive OSGi meets Reactive Java
Don’t cross the streams?
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Who is Tim Ward?
Chief Technology Officer at Paremus
9 years developing OSGi specifications
Co-chair of the OSGi IoT Expert Group
Interested in Asynchronous Distributed Systems
Author of Manning’s Enterprise OSGi in Action
http://www.manning.com/cummins
@TimothyWard
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
A quick introduction
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
What is Reactive Programming?
A set of principles for handling high volumes of “live” data
Live data may be historic, but not stored for batch processing
Changes should be “reactive” and reflected immediately
Operations are stream-centric
Resource utilisation must be controlled
Asynchronous exchange of data to decouple processing
Non-blocking back-pressure to limit the rate of event production
Concepts described at https://www.reactivemanifesto.org
Standardisation at http://www.reactive-streams.org
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Reactive Java specifications
The Reactive Streams initiative
Defines the org.reactivestreams API, a specification and a TCK
Does not define an implementation
OSGi PushStreams
Defines the org.osgi.util.pushstream API
The API is self-implementing
The Java 9 Flow API
A simple re-namespacing of the Reactive Streams API
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
The reactive primitives
Reactive
Streams / Java 9 PushStreams
Event / Data
Source
Publisher<T> PushEventSource<T>
Event / Data
Sink
Subscriber<T> PushEventConsumer<T>
“Connection” Subscription AutoCloseable
“Pipeline” Processor<T,R> PushStream<T>
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Being Reactive
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Reactive examples
In the following examples:
The data stream is a monotonic infinite sequence from 0
Data events occur every 50 ms
The consumer wants to print out the first N events
The consumer wants to print out when they are finished
This is a fairly simple, but practical example case
Short circuiting is necessary for infinite streams!
Let’s compare OSGi Push Streams and Reactive Streams
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Push Streams
Demo code…
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Push Streams (2)
Highlights:
The SimplePushEventSource is powerful
It can multiplex multiple consumers from a single event stream
It is internally buffered to protect against slow consumers
It uses callbacks to allow lazy event generation
The PushStream offers a familiar processing pipeline model
There is no dependency on the rest of the OSGi API
Easy to deploy in “standard Java”
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Reactive Streams
Demo code…
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Reactive Streams (2)
The code looks pretty horrible, right?
This wasn’t really a fair fight…
Reactive Streams is a pure API
Any non-trivial application must use an implementation
The same is true of Java 9’s Flow API!
A fairer comparison would be to use a library
RxJava was originally from Netflix, and is widely used
Note that the example also ran faster…
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Rx Java
Demo code…
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Rx Java (2)
This example is super-concise
It isn’t really a fair comparison either!
The other examples use async “push” publication
Most RxJava methods make data “on demand”
This is one reason why the raw API version ran faster too!
We need to move publication onto a different thread…
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Rx Java (3)
Demo code…
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Rx Java (4)
The code is now very similar to the Push Stream example
This is unsurprising, as the primitives are pretty similar
So what actually is the difference?
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
The differences
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Creating the connection
Connecting a source and consumer is subtly different:
AutoCloseable open(PushEventConsumer<T> pec)
void subscribe(Subscriber<T> s)
A Reactive Stream cannot be closed by the creator!
The subscription can do this but it is hidden
RxJava’s Disposable isn’t the same
Reactive Streams are not (in general) Lambda friendly
The Subscriber has four methods, and must be stateful
Specific libraries try to work around this
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
The way events are propagated
A Subscriber must request data before it can be sent
The data cannot be delivered concurrently
This is Thread Safe, and reduces CPU exhaustion
Push Streams can push data whenever they like
In general event delivery is concurrent (see sequential())
Pipeline functions should be stateless and/or Thread Safe
Back pressure need not be honoured by the source
In many cases these differences have no effect
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Publishers - Hot, Cold, Push and Pull
Sources of events can have different characteristics
Cold sources can be restarted from the beginning (e.g. a List)
Hot sources provide live data and cannot restart (e.g. a sensor)
Pull sources provide data “on request”
Push sources provide data as a result of something
Cold sources are almost always Pull
Reactive Streams work well for Pull sources
Data can only be sent after it is requested
Push Streams API work well for Push sources
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Coping with slow consumers
Event processing is easy when the consumer is fast
If a Push source is faster than the consumer we have a problem!
Reactive Streams must always use buffers for Push sources
This is because Subscribers must be called on request
Pushstreams use the incoming thread to receive data
Pushed data on multiple threads is processed in parallel
Long running/blocking operations should use their own thread(s)
Buffering is still valuable as it releases the publisher thread
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Coping with slow consumers (2)
Buffering is only part of the solution!
Buffers cannot be infinite (OutOfMemoryError)
Buffers solve “bursts” not a long term mismatch in speed
Reactive Streams require you to “fan out”
Spread the processing over multiple streams
Often this uses a new process (see Akka)
Pushstreams can simply use more threads!
Buffers allow the number of workers to scale up or down
Use the buffer to solve both bursts and speed up
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Coping with slow consumers (3)
We can only get so far by speeding up the consumer
We need to use back pressure to slow down the data source
Reactive Streams back pressure is controlled by request
This helps with Pull sources, but how does it help with Push?
How long should we hold/drop data for?
Pushstreams return a “delay” that should be observed
Dropping messages for the period may make sense
A periodic producer may be able to slow down
A Push source with important messages is always a challenge
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Slow consumer examples
In the following examples:
The data stream is a monotonic infinite sequence from 0
The data stream produces events every 50 ms
The consumer wants to print out the first 500 events
The consumer takes 80 ms per event
The examples may process the stream on N threads
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Slow consumer examples (2)
Demo code…
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Library comparisons
Both libraries are easy to deploy (small dependency graph)
The default PushStream implementation is small (110kb)
Rx Java 2.1.4 is 2100kb (> 10% the size of a custom Java 9 JVM!)
The API decisions match the original use cases
Handling Hot, Push data events from IoT sensors/message queues
Rescaling video streams based on user backpressure
This is why Push Streams work naturally with multiple threads
The Reactive Streams API is useless, except as an SPI
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Making use of Reactive Streams
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Library interoperability
The Reactive Streams API is good for library interoperation
A standard PushStream can be treated as a Publisher
A standard Publisher can be treated as a PushEventSource
This means that any Stream can be linked to any other!
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Interoperation examples
Demo code…
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
Questions?
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017
For more about OSGi...
Specifications at http://www.osgi.org
Enterprise OSGi in Action
For more about the Push Streams
https://www.osgi.org/developer/specifications/
http://oss.sonatype.org/content/groups/osgi/
For more about Reactive Streams/Rx Java
https://github.com/ReactiveX/RxJava
http://www.reactive-streams.org
Thanks!
http://www.paremus.com
info@paremus.com
http://www.manning.com/
cummins
We look forward to seeing you tomorrow morning
Copyright © 2017 Paremus Ltd.

May not be reproduced by any means without express permission. All rights reserved.
Reactive OSGi meets Reactive Java October 2017

Reactive OSGi meets Reactive Java - Don’t cross the streams - T Ward

  • 1.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Tim Ward
 tim.ward@paremus.com Reactive OSGi meets Reactive Java Don’t cross the streams?
  • 2.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Who is Tim Ward? Chief Technology Officer at Paremus 9 years developing OSGi specifications Co-chair of the OSGi IoT Expert Group Interested in Asynchronous Distributed Systems Author of Manning’s Enterprise OSGi in Action http://www.manning.com/cummins @TimothyWard
  • 3.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 A quick introduction
  • 4.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 What is Reactive Programming? A set of principles for handling high volumes of “live” data Live data may be historic, but not stored for batch processing Changes should be “reactive” and reflected immediately Operations are stream-centric Resource utilisation must be controlled Asynchronous exchange of data to decouple processing Non-blocking back-pressure to limit the rate of event production Concepts described at https://www.reactivemanifesto.org Standardisation at http://www.reactive-streams.org
  • 5.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Reactive Java specifications The Reactive Streams initiative Defines the org.reactivestreams API, a specification and a TCK Does not define an implementation OSGi PushStreams Defines the org.osgi.util.pushstream API The API is self-implementing The Java 9 Flow API A simple re-namespacing of the Reactive Streams API
  • 6.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 The reactive primitives Reactive Streams / Java 9 PushStreams Event / Data Source Publisher<T> PushEventSource<T> Event / Data Sink Subscriber<T> PushEventConsumer<T> “Connection” Subscription AutoCloseable “Pipeline” Processor<T,R> PushStream<T>
  • 7.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Being Reactive
  • 8.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Reactive examples In the following examples: The data stream is a monotonic infinite sequence from 0 Data events occur every 50 ms The consumer wants to print out the first N events The consumer wants to print out when they are finished This is a fairly simple, but practical example case Short circuiting is necessary for infinite streams! Let’s compare OSGi Push Streams and Reactive Streams
  • 9.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Push Streams Demo code…
  • 10.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Push Streams (2) Highlights: The SimplePushEventSource is powerful It can multiplex multiple consumers from a single event stream It is internally buffered to protect against slow consumers It uses callbacks to allow lazy event generation The PushStream offers a familiar processing pipeline model There is no dependency on the rest of the OSGi API Easy to deploy in “standard Java”
  • 11.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Reactive Streams Demo code…
  • 12.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Reactive Streams (2) The code looks pretty horrible, right? This wasn’t really a fair fight… Reactive Streams is a pure API Any non-trivial application must use an implementation The same is true of Java 9’s Flow API! A fairer comparison would be to use a library RxJava was originally from Netflix, and is widely used Note that the example also ran faster…
  • 13.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Rx Java Demo code…
  • 14.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Rx Java (2) This example is super-concise It isn’t really a fair comparison either! The other examples use async “push” publication Most RxJava methods make data “on demand” This is one reason why the raw API version ran faster too! We need to move publication onto a different thread…
  • 15.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Rx Java (3) Demo code…
  • 16.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Rx Java (4) The code is now very similar to the Push Stream example This is unsurprising, as the primitives are pretty similar So what actually is the difference?
  • 17.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 The differences
  • 18.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Creating the connection Connecting a source and consumer is subtly different: AutoCloseable open(PushEventConsumer<T> pec) void subscribe(Subscriber<T> s) A Reactive Stream cannot be closed by the creator! The subscription can do this but it is hidden RxJava’s Disposable isn’t the same Reactive Streams are not (in general) Lambda friendly The Subscriber has four methods, and must be stateful Specific libraries try to work around this
  • 19.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 The way events are propagated A Subscriber must request data before it can be sent The data cannot be delivered concurrently This is Thread Safe, and reduces CPU exhaustion Push Streams can push data whenever they like In general event delivery is concurrent (see sequential()) Pipeline functions should be stateless and/or Thread Safe Back pressure need not be honoured by the source In many cases these differences have no effect
  • 20.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Publishers - Hot, Cold, Push and Pull Sources of events can have different characteristics Cold sources can be restarted from the beginning (e.g. a List) Hot sources provide live data and cannot restart (e.g. a sensor) Pull sources provide data “on request” Push sources provide data as a result of something Cold sources are almost always Pull Reactive Streams work well for Pull sources Data can only be sent after it is requested Push Streams API work well for Push sources
  • 21.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Coping with slow consumers Event processing is easy when the consumer is fast If a Push source is faster than the consumer we have a problem! Reactive Streams must always use buffers for Push sources This is because Subscribers must be called on request Pushstreams use the incoming thread to receive data Pushed data on multiple threads is processed in parallel Long running/blocking operations should use their own thread(s) Buffering is still valuable as it releases the publisher thread
  • 22.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Coping with slow consumers (2) Buffering is only part of the solution! Buffers cannot be infinite (OutOfMemoryError) Buffers solve “bursts” not a long term mismatch in speed Reactive Streams require you to “fan out” Spread the processing over multiple streams Often this uses a new process (see Akka) Pushstreams can simply use more threads! Buffers allow the number of workers to scale up or down Use the buffer to solve both bursts and speed up
  • 23.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Coping with slow consumers (3) We can only get so far by speeding up the consumer We need to use back pressure to slow down the data source Reactive Streams back pressure is controlled by request This helps with Pull sources, but how does it help with Push? How long should we hold/drop data for? Pushstreams return a “delay” that should be observed Dropping messages for the period may make sense A periodic producer may be able to slow down A Push source with important messages is always a challenge
  • 24.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Slow consumer examples In the following examples: The data stream is a monotonic infinite sequence from 0 The data stream produces events every 50 ms The consumer wants to print out the first 500 events The consumer takes 80 ms per event The examples may process the stream on N threads
  • 25.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Slow consumer examples (2) Demo code…
  • 26.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Library comparisons Both libraries are easy to deploy (small dependency graph) The default PushStream implementation is small (110kb) Rx Java 2.1.4 is 2100kb (> 10% the size of a custom Java 9 JVM!) The API decisions match the original use cases Handling Hot, Push data events from IoT sensors/message queues Rescaling video streams based on user backpressure This is why Push Streams work naturally with multiple threads The Reactive Streams API is useless, except as an SPI
  • 27.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Making use of Reactive Streams
  • 28.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Library interoperability The Reactive Streams API is good for library interoperation A standard PushStream can be treated as a Publisher A standard Publisher can be treated as a PushEventSource This means that any Stream can be linked to any other!
  • 29.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Interoperation examples Demo code…
  • 30.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 Questions?
  • 31.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017 For more about OSGi... Specifications at http://www.osgi.org Enterprise OSGi in Action For more about the Push Streams https://www.osgi.org/developer/specifications/ http://oss.sonatype.org/content/groups/osgi/ For more about Reactive Streams/Rx Java https://github.com/ReactiveX/RxJava http://www.reactive-streams.org Thanks! http://www.paremus.com info@paremus.com http://www.manning.com/ cummins We look forward to seeing you tomorrow morning
  • 32.
    Copyright © 2017Paremus Ltd. May not be reproduced by any means without express permission. All rights reserved. Reactive OSGi meets Reactive Java October 2017