139
Supercharge your (reactive) Streams

Javaone 2016 : Supercharge your (reactive) Streams

Embed Size (px)

Citation preview

Page 1: Javaone 2016 : Supercharge your (reactive) Streams

Superchargeyour (reactive)

Streams

Page 2: Javaone 2016 : Supercharge your (reactive) Streams

2

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classes

Visualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 3: Javaone 2016 : Supercharge your (reactive) Streams
Page 4: Javaone 2016 : Supercharge your (reactive) Streams

A

A

A

P

P

P

Exchange

Page 5: Javaone 2016 : Supercharge your (reactive) Streams

RTB Ad Cycle

100 ms

20,000,000,000+

Page 6: Javaone 2016 : Supercharge your (reactive) Streams

6

multi-core

Page 7: Javaone 2016 : Supercharge your (reactive) Streams

Race Conditions

Deadlocks

Contention

Non-Deterministic State

Thread StarvationLivelocks

Page 8: Javaone 2016 : Supercharge your (reactive) Streams

8

Forecasting

Page 9: Javaone 2016 : Supercharge your (reactive) Streams

9

Page 10: Javaone 2016 : Supercharge your (reactive) Streams

Price / Volume Curve

Page 11: Javaone 2016 : Supercharge your (reactive) Streams

Forecasting

11

Campaign Planning and Optimization

Query data across petabytes data

Accuracy & ResponsivenessBid Request RecordsPer Day

Impression RecordsPer Day

Viewability RecordsPer Day

20B 2B 2B

Page 12: Javaone 2016 : Supercharge your (reactive) Streams

12

Speed

Page 13: Javaone 2016 : Supercharge your (reactive) Streams

Indexing

13

Page 14: Javaone 2016 : Supercharge your (reactive) Streams

14

Page 15: Javaone 2016 : Supercharge your (reactive) Streams

15

Expectations

Page 16: Javaone 2016 : Supercharge your (reactive) Streams

16

Reality

Page 17: Javaone 2016 : Supercharge your (reactive) Streams

17

Phew!

Page 18: Javaone 2016 : Supercharge your (reactive) Streams

18

Oops!

Page 19: Javaone 2016 : Supercharge your (reactive) Streams

19

Why?

Page 20: Javaone 2016 : Supercharge your (reactive) Streams

Why is it like this?

20

Page 21: Javaone 2016 : Supercharge your (reactive) Streams

21

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classes

Visualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 22: Javaone 2016 : Supercharge your (reactive) Streams

22

Immutable

Page 23: Javaone 2016 : Supercharge your (reactive) Streams

Declarative 23

Page 24: Javaone 2016 : Supercharge your (reactive) Streams

Functional?

24

Page 25: Javaone 2016 : Supercharge your (reactive) Streams

25

List<NormalizedElement> logs;

logs = logEntries.stream() .filter(log->log.elements.size()>100)

.flatMap(Log::elements) .map(this::normalize) .collect(Collectors.toList());

Functional

Page 26: Javaone 2016 : Supercharge your (reactive) Streams
Page 27: Javaone 2016 : Supercharge your (reactive) Streams

27

PriorityLevel speed = request.flatMap(Request::getUser) .flatMap(User::getPriority) .map(p->p.getLevel(service)) .orElse(PriorityLevel.SLOW);

Optional

Page 28: Javaone 2016 : Supercharge your (reactive) Streams

functions.stream() .map(it -> it.apply(visit)) .flatMap(Collection::stream) .flatMap(v1 -> { functions2.stream() .map(it -> it.apply(time)) .flatMap(Collection::stream) .map(v2 -> join(v1,v2)) .collect(Collectors.toList()); }) .map(this::processJoinedEntry) .filter(Entry::isActive) .flatMap(Entry::subEntries) .flatMap(v3-> { functions3.stream() .map(it -> it.apply(time)) .flatMap(Collection::stream) .map(v4 -> join(v3,v4)) .collect(Collectors.toList());

});

Complexity

28

Page 29: Javaone 2016 : Supercharge your (reactive) Streams

functions.stream() .map(it -> it.apply(visit)) .flatMap(Collection::stream) .flatMap(v1 -> { functions2.stream() .map(it -> it.apply(time)) .flatMap(Collection::stream) .map(v2 -> join(v1,v2)) .collect(Collectors.toList()); }) .map(this::processJoinedEntry) .filter(Entry::isActive) .flatMap(Entry::subEntries) .flatMap(v3-> { functions3.stream() .map(it -> it.apply(time)) .flatMap(Collection::stream) .map(v4 -> join(v3,v4)) .collect(Collectors.toList());

});

29

Page 30: Javaone 2016 : Supercharge your (reactive) Streams

30

PURE

Page 31: Javaone 2016 : Supercharge your (reactive) Streams

31

Easier to test

Page 32: Javaone 2016 : Supercharge your (reactive) Streams

32

Optimizable

Page 33: Javaone 2016 : Supercharge your (reactive) Streams

33

No side effects

Page 34: Javaone 2016 : Supercharge your (reactive) Streams

Set<String> data;

public void populateData(){for(int i=0;i<100;i++){

String nextFile = prefix+i; data.add(transform(nextFile));

}}Side effects

34

Page 35: Javaone 2016 : Supercharge your (reactive) Streams

PURE

35

public Set<String> populateData(){ Stream.iterate(0,i->i+1) .limit(100) .map(i->"prefix"+i) .map(this::transform) .collect(Collectors.toSet());}

Page 36: Javaone 2016 : Supercharge your (reactive) Streams

36

Stream.iterate(0,i->i+1) .limit(100) .map(i->"prefix"+i) .map(this::transform) .collect(Collectors.toSet());

Page 37: Javaone 2016 : Supercharge your (reactive) Streams

Paralle

l

37

Stream.iterate(0,i->i+1) .limit(100) .parallel() .map(i->"prefix"+i) .map(this::transform) .collect(Collectors.toSet());

Page 38: Javaone 2016 : Supercharge your (reactive) Streams

Paralle

lize

Testable?38

Set<String> data;

public void populateData() {for(int i=0;i<100;i++){

String nextFile = prefix+i; data.add(transform(nextFile));

}}

Page 39: Javaone 2016 : Supercharge your (reactive) Streams

39

Traditional Imperative Java

Java 8

Mutable Immutable

Stateful Stateless

Page 40: Javaone 2016 : Supercharge your (reactive) Streams

Concurrent app?40

public Set<String> populateData(){ return Stream.iterate(0,i->i+1) .limit(100) .map(i->"prefix"+i) .map(this::transform) .collect(Collectors.toSet());}

Set<String> data;

public void populateData() {for(int i=0;i<100;i++){

String nextFile = prefix+i; data.add(transform(nextFile));

}}

Page 41: Javaone 2016 : Supercharge your (reactive) Streams

41

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classes

Visualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 42: Javaone 2016 : Supercharge your (reactive) Streams

42

Microservice

example

Page 43: Javaone 2016 : Supercharge your (reactive) Streams

Read / Transform / Write

43

Stream.generate(this::pollS3). .map(this::processAndTransform) .map(this::storeInS3)

Page 44: Javaone 2016 : Supercharge your (reactive) Streams

44

ScheduleStream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3)

Page 45: Javaone 2016 : Supercharge your (reactive) Streams

45

StreamUtils.scheduleFixedDelay(Stream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3), 20_000, executor))

Schedule

Page 46: Javaone 2016 : Supercharge your (reactive) Streams

46

StreamUtils.scheduleFixedDelay(Stream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3), 20_000, executor))

Schedule

Page 47: Javaone 2016 : Supercharge your (reactive) Streams

47

Page 48: Javaone 2016 : Supercharge your (reactive) Streams

48

Page 49: Javaone 2016 : Supercharge your (reactive) Streams

49

Page 50: Javaone 2016 : Supercharge your (reactive) Streams

50

StreamUtils.scheduleFixedDelay(Stream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3), 20_000, executor))

A Snag

Page 51: Javaone 2016 : Supercharge your (reactive) Streams

51

public Data pollS3() throws AmazonServiceException, AmazonClientException

Page 52: Javaone 2016 : Supercharge your (reactive) Streams

52

Page 53: Javaone 2016 : Supercharge your (reactive) Streams

53

Page 54: Javaone 2016 : Supercharge your (reactive) Streams

54

Page 55: Javaone 2016 : Supercharge your (reactive) Streams

55

StreamUtils.scheduleFixedDelay(Stream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3), 20_000, executor))

Error Handling

Page 56: Javaone 2016 : Supercharge your (reactive) Streams

56

StreamUtils.scheduleFixedDelay(StreamUtils.recover(Stream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3),e->false), 20_000,

executor))

Error Handling

Page 57: Javaone 2016 : Supercharge your (reactive) Streams

57

StreamUtils.scheduleFixedDelay(StreamUtils.recover(Stream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3),e->false), 20_000,

executor))

Error Handling

Page 58: Javaone 2016 : Supercharge your (reactive) Streams

58

Page 59: Javaone 2016 : Supercharge your (reactive) Streams

59

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classesVisualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 60: Javaone 2016 : Supercharge your (reactive) Streams

60

StreamUtils.scheduleFixedDelay(StreamUtils.recover(Stream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3),e->false), 20_000,

executor))

Page 61: Javaone 2016 : Supercharge your (reactive) Streams

Read / Transform / Write

61

Stream.generate(this::pollS3). .map(this::processAndTransform) .map(this::storeInS3)

Page 62: Javaone 2016 : Supercharge your (reactive) Streams

62

ReactiveSeq.generate(this::pollS3). .map(this::processAndTransform) .map(this::storeInS3);

Extended Stream

Page 63: Javaone 2016 : Supercharge your (reactive) Streams

63

ReactiveSeq.generate(this::pollS3). .map(this::processAndTransform) .map(this::storeInS3)

.recover(e->false) .scheduleFixedDelay(20_000,executor)

Extension methods

Page 64: Javaone 2016 : Supercharge your (reactive) Streams

64

Page 65: Javaone 2016 : Supercharge your (reactive) Streams

65

Page 66: Javaone 2016 : Supercharge your (reactive) Streams

66

Page 67: Javaone 2016 : Supercharge your (reactive) Streams

Seq

67

Stream

ReactiveSeq

Page 68: Javaone 2016 : Supercharge your (reactive) Streams

68

Page 69: Javaone 2016 : Supercharge your (reactive) Streams

uential69

Seq.of("a","b","c","d") .map(String::toUpperCase) .zipWithIndex() .filter(t->t.v2%2==0) .sliding(3) .duplicate();

interface Seq extends Stream { }

Seq.of(1, 2, 4)

.rightOuterJoin(Seq.of(1, 2, 3), (a, b) -> a == b);

Seq

Page 70: Javaone 2016 : Supercharge your (reactive) Streams

70

ReactiveSeq.of(1,2,3) .map(this::load) .recover(e->"default value") .retry(this::unreliableMethod);

Error HandlingError handling

Page 71: Javaone 2016 : Supercharge your (reactive) Streams

71

ReactiveSeq.of(1,2,3,4) .futureOperations(Executors.newFixedThreadPool(1)) .forEach(this::expensiveOp);

Asynchronous execution

Error handlingAsync execution

Page 72: Javaone 2016 : Supercharge your (reactive) Streams

Scheduling

72

ReactiveSeq.of(1,2,3) .schedule("* * * * * ?", Executors.newScheduledThreadPool(1)) .connect() .debounce(1, TimeUnit.SECONDS) .forEach(System.out::println);

Error handlingAsync executionScheduling

Page 73: Javaone 2016 : Supercharge your (reactive) Streams

73

ReactiveSeq<Integer> stream = ReactiveSeq.of(1,2,3,4);Subscription s = stream.forEachXEvents(2, System.out::println, System.err::println, ()->System.out.println("complete")); s.request(2);

Subscriptions& Events

Error handlingAsync executionSchedulingSubscriptions

Page 74: Javaone 2016 : Supercharge your (reactive) Streams

reactive-streams

74

interface ReactiveSeq extends Seq, Stream, Publisher { }

SeqSubscriber<Integer> sub = SeqSubscriber.subscriber(); Flux.just(1,2,3,4) .map(i->i*2) .subscribe(sub); ReactiveSeq<Integer> connected = sub.stream();

Error handlingAsync executionSchedulingSubscriptionsreactive-streams

Page 75: Javaone 2016 : Supercharge your (reactive) Streams

75

Page 76: Javaone 2016 : Supercharge your (reactive) Streams

Parallel

76

new LazyReact().of(1,2,3,4) .map(this::load) .forEach(this::save);

interface LazyFutureStream extends ReactiveSeq, Seq, Stream, Publisher { }

Error handlingAsync executionSchedulingSubscriptionsreactive-streamsFuture streams

Page 77: Javaone 2016 : Supercharge your (reactive) Streams

Optional

Stream

CompletableFuture

ReactiveSeqLazyFutureStream

ListX

FutureW

Maybe

Try

Xor

Eval

SetX

PStackXPVectorX

PSetX

Page 78: Javaone 2016 : Supercharge your (reactive) Streams

78

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classes

Visualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 79: Javaone 2016 : Supercharge your (reactive) Streams

JDK Sequential Stream

79

.map(e -> e*100)

.forEach(System.out::println)

.filter(e -> e<551)

Stream.of(6,5,1,2)

Page 80: Javaone 2016 : Supercharge your (reactive) Streams

Sequential Stream

80

first stage(map)

second stage(filter)

terminal stage (forEach)

Page 81: Javaone 2016 : Supercharge your (reactive) Streams

Sequential Stream

81

first stage(map)

second stage(filter)

terminal stage (forEach)

500

2

1

5 600

Page 82: Javaone 2016 : Supercharge your (reactive) Streams

JDK Parallel Stream

82

.map(e -> e*100)

.forEach(System.out::println)

.filter(e -> e<551)

Stream.of(6,5,1,2)

.parallel()

Page 83: Javaone 2016 : Supercharge your (reactive) Streams

Parallel Stream

83

terminal stage

(forEach)

first stage(map)

second stage(filter)

first stage(map)

second stage(filter)

first stage(map)

second stage(filter)

first stage(map)

second stage(filter)

elements 1..n

elements 1..n/2

elements n/2..n

elements 1..n/4

elements n/4..n/2

elements n/2..3/4n

elements 3/4n..n

Page 84: Javaone 2016 : Supercharge your (reactive) Streams

84

Alternatives?

Page 85: Javaone 2016 : Supercharge your (reactive) Streams

85

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classes

Visualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 86: Javaone 2016 : Supercharge your (reactive) Streams

86

CPU

Page 87: Javaone 2016 : Supercharge your (reactive) Streams

Sequential Stream

87

first stage(map)

second stage(filter)

terminal stage (forEach)

Page 88: Javaone 2016 : Supercharge your (reactive) Streams

88

first stage(map)

second stage(filter)

terminal stage (forEach)core 1

first stage(map)

second stage(filter)

terminal stage (forEach)core 2

first stage(map)

second stage(filter)

terminal stage (forEach)core 3

first stage(map)

second stage(filter)

terminal stage (forEach)core 4

Parallel Pipelines

Sequential Streams

Page 89: Javaone 2016 : Supercharge your (reactive) Streams

89

Parallel Pipelinesfirst stage

(map)second stage

(filter)terminal stage

(forEach)core 1 third stage(target thread)

first stage(map)

second stage(filter)

terminal stage (forEach)core 2 third stage

(target thread)

first stage(map)

second stage(filter)

terminal stage (forEach)core 3 third stage

(target thread)

first stage(map)

second stage(filter)

terminal stage (forEach)core 4 third stage

(target thread)

Page 90: Javaone 2016 : Supercharge your (reactive) Streams

90

ReactiveSeq

Page 91: Javaone 2016 : Supercharge your (reactive) Streams

Sequential Stream

91

.map(e -> e*100)

.forEach(System.out::println)

.filter(e -> e<551)

ReactiveSeq.of(6,5,1,2)

.futureOperations(executor)

Page 92: Javaone 2016 : Supercharge your (reactive) Streams

92

Page 93: Javaone 2016 : Supercharge your (reactive) Streams

93

Page 94: Javaone 2016 : Supercharge your (reactive) Streams

94

Page 95: Javaone 2016 : Supercharge your (reactive) Streams

95

Page 96: Javaone 2016 : Supercharge your (reactive) Streams

96

Page 97: Javaone 2016 : Supercharge your (reactive) Streams

97

Page 98: Javaone 2016 : Supercharge your (reactive) Streams

98

Page 99: Javaone 2016 : Supercharge your (reactive) Streams

Performance

99

Low

er is

bet

ter

Page 100: Javaone 2016 : Supercharge your (reactive) Streams

100

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classes

Visualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 101: Javaone 2016 : Supercharge your (reactive) Streams

101

I/O

Page 102: Javaone 2016 : Supercharge your (reactive) Streams

102

first stage(map)

second stage(filter)

terminal stage (forEach)

future 1

future 2

future 3

future 4

future 5

future 6

future 7

future 8

future 9

future 10 future

11

Concurrent tasks

Page 103: Javaone 2016 : Supercharge your (reactive) Streams

103

Future

Page 104: Javaone 2016 : Supercharge your (reactive) Streams

Async I/O CompletableFuture

104

.thenApply(e -> e*100)

CompletableFuture.supplyAsync(this::load)

.thenAccept(e ->{ if(e<551) System.out.println(e); } );

Page 105: Javaone 2016 : Supercharge your (reactive) Streams

Async I/O

105

.map(e -> e*100)

.peek(System.out::println)

.filter(e -> e<551)

FutureW.ofSupplier(this::load)

Page 106: Javaone 2016 : Supercharge your (reactive) Streams

106

FutureStream

Page 107: Javaone 2016 : Supercharge your (reactive) Streams

Stream of CompletableFutures

107

.map(f ->f.thenApply(e-> e*100))

.peek(f-> f.thenAccept(System.out::println))

Stream.of(6,5,1,2) .map(e->CompletableFuture.supplyAsync(this::load,executor))

.filter( here be dragons)

.collect(Collectors.toList()) //join each elem

Page 108: Javaone 2016 : Supercharge your (reactive) Streams

Stream of Futures

108

.map(f ->f.map(e-> e*100))

Stream.of(6,5,1,2)

.map(e->FutureW.ofSupplier(this::load,executor))

.peek(f-> f.peek(System.out::println)) .collect(Collectors.toList()) //join each

elem

.filter(here be dragons)

Page 109: Javaone 2016 : Supercharge your (reactive) Streams

FutureStream

109

.map(e -> e*100)

.forEach(System.out::println)

.filter(e -> e<551)

new LazyReact(executor).of(6,5,1,2).map(this::loadData)

Page 110: Javaone 2016 : Supercharge your (reactive) Streams

110

Page 111: Javaone 2016 : Supercharge your (reactive) Streams

111

Page 112: Javaone 2016 : Supercharge your (reactive) Streams

112

Page 113: Javaone 2016 : Supercharge your (reactive) Streams

Performance

113

Low

er is

bet

ter

Page 114: Javaone 2016 : Supercharge your (reactive) Streams

Indexing

114

Page 115: Javaone 2016 : Supercharge your (reactive) Streams

Reactive Indexing Architecture

115

Page 116: Javaone 2016 : Supercharge your (reactive) Streams

116

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classes

Visualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 117: Javaone 2016 : Supercharge your (reactive) Streams

117

Queues

Page 118: Javaone 2016 : Supercharge your (reactive) Streams

118

Page 119: Javaone 2016 : Supercharge your (reactive) Streams

Create a Queue

119

Wrapped Queue Type : Bounded Blocking Queue

QueueFactories. <Data>boundedQueue(1_000) .build();

Page 120: Javaone 2016 : Supercharge your (reactive) Streams

Reading from Queues

120

Queue<Data> transfer; transfer.stream() .forEach(this::process);

Page 121: Javaone 2016 : Supercharge your (reactive) Streams

Writing to Queues

121

Queue<Data> transfer;

new LazyReact(executor).generate(this::loadNext) .map(this::process) .forEach(data->transfer.offer(data));

Page 122: Javaone 2016 : Supercharge your (reactive) Streams

Backpressure - FULL

122

Page 123: Javaone 2016 : Supercharge your (reactive) Streams

Backpressure - EMPTY

123

Page 124: Javaone 2016 : Supercharge your (reactive) Streams

124

Page 125: Javaone 2016 : Supercharge your (reactive) Streams

125

Page 126: Javaone 2016 : Supercharge your (reactive) Streams

126

Page 127: Javaone 2016 : Supercharge your (reactive) Streams

127

Page 128: Javaone 2016 : Supercharge your (reactive) Streams

128

Page 129: Javaone 2016 : Supercharge your (reactive) Streams

129

Concurrency is hard!

Does Java 8 help?

Extending Streams

Static methods Extension classes

Visualizing Streams

Parallel Streams

CPU Bound I/O Bound

Connecting Streams

A consistent Stream based Architecture

Page 130: Javaone 2016 : Supercharge your (reactive) Streams

Reactive Indexing Architecture

130

Page 131: Javaone 2016 : Supercharge your (reactive) Streams

131

Summary

Page 132: Javaone 2016 : Supercharge your (reactive) Streams

Easier to parellize?

132

public Set<String> populateData(){ return Stream.iterate(0,i->i+1) .limit(100) .map(i->"prefix"+i) .map(this::transform) .collect(Collectors.toSet());}

Set<String> data;

public void populateData() {for(int i=0;i<100;i++){

String nextFile = prefix+i; data.add(transform(nextFile));

}}

Page 133: Javaone 2016 : Supercharge your (reactive) Streams

133

StreamUtils.scheduleFixedDelay(StreamUtils.recover(Stream.generate(this::pollS3).

.map(this::processAndTransform) .map(this::storeInS3),e->false), 20_000,

executor))

Extension methods have limits

Page 134: Javaone 2016 : Supercharge your (reactive) Streams

134

Richer sequential API

Page 135: Javaone 2016 : Supercharge your (reactive) Streams

Parallelism can be layered back in

135

.map(e -> e*100)

.forEach(System.out::println)

.filter(e -> e<551)

new LazyReact(executor).of(6,5,1,2).map(this::loadData)

Page 136: Javaone 2016 : Supercharge your (reactive) Streams

136

Transfer queues for advanced connections

Page 137: Javaone 2016 : Supercharge your (reactive) Streams

137

Check outcyclops-react.io

Page 138: Javaone 2016 : Supercharge your (reactive) Streams

Thank You.

Page 139: Javaone 2016 : Supercharge your (reactive) Streams

139

Pics:Ducks and Cat by https://www.flickr.com/photos/11325321@N08/ under CC2