187
Real-time Insights powered by Reactive Programming Jay Phelps | @_jayphelps

Real-time Insights, powered by Reactive Programming

Embed Size (px)

Citation preview

Page 1: Real-time Insights, powered by Reactive Programming

Real-time Insights powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 2: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Let's talk why

Page 3: Real-time Insights, powered by Reactive Programming
Page 4: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Time is money

Page 5: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

127+ million person-hours lost

per year

$500k — $1+ million

per hour average hourly cost of

critical failure

https://devops.com/real-cost-downtime/

Fortune 500

Page 6: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Every second counts

Page 7: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Not just outages...

Page 8: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

debugging, testing, and even Information Security too

Page 9: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

improving Developer Experience

Page 10: Real-time Insights, powered by Reactive Programming

Senior Software Engineer |

@_jayphelps

Jay Phelps

Page 11: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

debugging, testing, and InfoSec

Page 12: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

InfoSec

“preventing unauthorized access, use, or disruption of information”

Page 13: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

stopping hackers

Page 14: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

InfoSec

Page 15: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 16: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

I'm on it.

Page 17: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We can block exploits using our gateway proxy

Page 18: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

...we need to know it's working...

Page 19: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

...we want to watch attackers try...

Page 20: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

...in real-time

Page 21: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We need real-time insights For debugging, testing, and InfoSec

Page 22: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Logging is the answer

Page 23: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

LOG ALL THE THINGSLOG ALL THE THINGSLOG ALL THE THINGSLOG ALL THE THINGSLOG ALL THE THINGS

Page 24: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

One little problem...

Page 25: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We have millions of devices...

Page 26: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We have thousands of servers...

Page 27: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We need to process them in real-time

Page 28: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

“Netflix is a log generating company that happens to stream movies” - Adrian Cockroft

Page 29: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Massive amount of streaming logs

Page 30: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Reactive Extensions

Page 31: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Rx

Page 32: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

The best ideas from the Observer pattern, the Iterator pattern, and functional programming

Page 33: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

“lodash for events”

Page 34: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 35: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 36: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

High-level intro

Page 37: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

[1,2,3]

Page 38: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

[1,2,3]

Page 39: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

[1,2,3]

Page 40: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

[1,2,3]

Page 41: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

[1,2,3]

Page 42: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

[1,2,3]

//10

Page 43: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

[1,2,3]

//10//20

Page 44: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

[1,2,3]

//10//20//30

Page 45: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

[1,2,3]

//10//20//30

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

Page 46: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

[1,2,3]

//10//20//30

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

Page 47: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.of(1,2,3)

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

Page 48: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.of(1,2,3)

.map(value=>value*10)

.forEach(value=>{

console.log(value);

});

Page 49: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.of(1,2,3)

.map(value=>value*10)

.subscribe(value=>{

console.log(value);

});

Page 50: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.of(1,2,3)

.map(value=>value*10)

.subscribe(value=>{

console.log(value);

});

Page 51: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.of(1,2,3)

//10

.map(value=>value*10)

.subscribe(value=>{

console.log(value);

});

Page 52: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.of(1,2,3)

//10//20

.map(value=>value*10)

.subscribe(value=>{

console.log(value);

});

Page 53: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.of(1,2,3)

//10//20//30

.map(value=>value*10)

.subscribe(value=>{

console.log(value);

});

Page 54: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Array is a collection

Page 55: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable is a collection that arrives over time

Page 56: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Represents a stream

Page 57: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

button.addEventListener('click',event=>{

console.log('youclicked!');

});

Page 58: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.subscribe(event=>{

console.log('youclicked!');

});

Page 59: Real-time Insights, powered by Reactive Programming

.subscribe(event=>{

console.log('youclicked!');

});

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.debounceTime(500)

Page 60: Real-time Insights, powered by Reactive Programming

.subscribe(event=>{

console.log('youclicked!');

});

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.debounceTime(500)

Page 61: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.debounceTime(500)

Page 62: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.debounceTime(500)

Page 63: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.debounceTime(500)

Page 64: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.debounceTime(500)

Page 65: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.debounceTime(500)

Page 66: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

Page 67: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

Page 68: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

Page 69: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

Page 70: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

Page 71: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

Page 72: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms

Page 73: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms

Page 74: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms

Page 75: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms

Page 76: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms

Page 77: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms

Page 78: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms

Page 79: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms

Page 80: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms 500 ms

Page 81: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms 500 ms

Page 82: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms 500 ms

Page 83: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms 500 ms

Page 84: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms 500 ms500 ms

Page 85: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms 500 ms500 ms

Page 86: Real-time Insights, powered by Reactive Programming

Observable.fromEvent(button,'click')

.debounceTime(500)

Jay Phelps | @_jayphelps

500 ms 500 ms500 ms

Page 87: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Observable.fromEvent(button,'click')

.debounceTime(500)

Page 88: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Stream of logs

Page 89: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

{

"path":"/something",

"status":500

}

Log message in JSON

Page 90: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

import{webSocket}from"rxjs/observable/webSocket";

letstreamOfLogs=webSocket("ws://logs.netflix.com")

Page 91: Real-time Insights, powered by Reactive Programming

.subscribe(msg=>{

console.log(msg);

});

Jay Phelps | @_jayphelps

streamOfLogs

.filter(msg=>msg.status!==200)

Page 92: Real-time Insights, powered by Reactive Programming

.subscribe(msg=>{

console.log(msg);

});

Jay Phelps | @_jayphelps

streamOfLogs

.filter(msg=>msg.status!==200)

Page 93: Real-time Insights, powered by Reactive Programming

500 200 404 301

Jay Phelps | @_jayphelps

500

streamOfLogs

.filter(msg=>msg.status!==200)

404

Page 94: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Learning Rx isn't easy

Page 95: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

It's worth it!

Page 96: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

It's worth it!Jay!!

Page 97: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Case Study

Scaling high volume logs in real-time

Page 98: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We're going to log JSON

Page 99: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

{

"path":"/something",

"status":200

}

Device{

"event":"StartPlay",

"device":"XBox360"

}

Server

Page 100: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Stream them all through a single pipeline

Page 101: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

How do you find and process the logs you want

Page 102: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Write a custom job in Java?

Page 103: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Job: a unit of work

Page 104: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

{

"path":"/something",

"status":500,

"duration":135,

//etc...

}

Server log message

Page 105: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

streamOfLogs

.filter(event->event.get("status")!=200)

.map(event->

newJSONObject()

.put("path",event.get("path"))

.put("status",event.get("status"))

);

Page 106: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Powerful, but... not ideal

Page 107: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Query Language

Page 108: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

SELECTpath,statusWHEREstatus!=200

Page 109: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Just-in-time (JIT) Compilation

Page 110: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

SELECTpath,status,durationWHEREstatus!=200

Page 111: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

SELECTpath,status,durationWHEREstatus!=200

Page 112: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

streamOfLogs

.filter(event->event.get("status")!=200)

.map(event->

newJSONObject()

.put("path",event.get("path"))

.put("status",event.get("status"))

);

SELECTpath,status,durationWHEREstatus!=200

Page 113: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

What's next?

Page 114: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

8+ million messages per second, peakm

essa

ges

per s

econ

d

Time

Page 115: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

How do we scale this?

Page 116: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Distribute work via autoscaling

Page 117: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

A

Source

B

Server

B

Server

50%

50%

Load balancing a job

Page 118: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Chain jobs together

Page 119: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

SELECTpath,statusWHEREsource=="API"

Chain jobs together

Page 120: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

A

Job

B C

Job Job

Chain jobs together

Page 121: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

High-volume, distributed systems have a problem...

Page 122: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Backpressure

Page 123: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

“pressure opposed to the desired flow of gases in confined places such as a pipe” - wikipedia.org

Page 124: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

A B C

Server Server Server

100 rps 75 rps

Page 125: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

A B C

Server Server Server

60 sec * 25 rps = 1,500 rpm!

100 rps 75 rps

Page 126: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

A B C

Server Server Server

100 rps 75 rps

60 sec * 60 min * 25 rps = 90,000 rph!

Page 127: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Buffer or Drop

Page 128: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

onBackpressureBuffer

Page 129: Real-time Insights, powered by Reactive Programming

.onBackpressureBuffer()

Jay Phelps | @_jayphelps

streamOfLogs

.subscribe(value->{

//somethingexpensive

Thread.sleep(100);

});

Page 130: Real-time Insights, powered by Reactive Programming

.onBackpressureBuffer()

Jay Phelps | @_jayphelps

streamOfLogs

.subscribe(value->{

//somethingexpensive

Thread.sleep(100);

});

Page 131: Real-time Insights, powered by Reactive Programming

.onBackpressureBuffer()

Jay Phelps | @_jayphelps

streamOfLogs

.subscribe(value->{

//somethingexpensive

Thread.sleep(100);

});

Page 132: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

1 2 3 4 5

.onBackpressureBuffer()

[3,4,5]

1 2

Page 133: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

onBackpressureDrop

Page 134: Real-time Insights, powered by Reactive Programming

.onBackpressureDrop()

streamOfLogs

.subscribe(value->{

//somethingexpensive

Thread.sleep(100);

});

Jay Phelps | @_jayphelps

Page 135: Real-time Insights, powered by Reactive Programming

.onBackpressureDrop()

streamOfLogs

.subscribe(value->{

//somethingexpensive

Thread.sleep(100);

});

Jay Phelps | @_jayphelps

Page 136: Real-time Insights, powered by Reactive Programming

.onBackpressureDrop()

streamOfLogs

.subscribe(value->{

//somethingexpensive

Thread.sleep(100);

});

Jay Phelps | @_jayphelps

Page 137: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

1 2 3 4 5

.onBackpressureDrop()

1 4

Page 138: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Job authors choose which

Page 139: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

700+ jobs running 24/7 8+ million events/second

Autoscaling

MantisLow-latency, high throughput stream-processing job platform

http://techblog.netflix.com

Page 140: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We need somewhere to submit and view query results

Page 141: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Query Builder UI

Page 142: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

SELECTpath,statusWHEREstatus!=200

Page 143: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 144: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 145: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 146: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 147: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 148: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Page 149: Real-time Insights, powered by Reactive Programming
Page 150: Real-time Insights, powered by Reactive Programming
Page 151: Real-time Insights, powered by Reactive Programming
Page 152: Real-time Insights, powered by Reactive Programming
Page 153: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Can be extremely high-volume

100k+ rps

Page 154: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We simply can’t render that fast!

Page 155: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Even if we could, it would be bad UX

Page 156: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Performance solutions are often driven by UX

Page 157: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

So what do we do?

Page 158: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

UI virtualization aka Virtual Table?

Page 159: Real-time Insights, powered by Reactive Programming

VirtualizedNOT Virtualized vs.

Page 160: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

We still can’t update that virtual table 100k per second

Page 161: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

This is also backpressure

Page 162: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Buffer or Drop

Page 163: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Buffer for 1 second

Page 164: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

getWebSocket()

.bufferTime(1000)

Page 165: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Buffer size is unbounded

Page 166: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

See what your users actually do

Page 167: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Users want a sample

Page 168: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Batch sampling

Page 169: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Drop after reaching a certain threshold

Page 170: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Batch sampling

Page 171: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Batch sampling

Page 172: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Batch sampling

Page 173: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Batch sampling

Page 174: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

letbuffer=getWebSocket()

.bufferTime(1000);

letgate=newBehaviorSubject(true);

letbatchSize=50;

letbatchSizeCounter=0;

letresults=gate$

.switchMap(enabled=>enabled?buffer:Observable.never())

.do(buffer=>{

batchSizeCounter+=buffer.length;

if(batchSizeCounter>=batchSize){

//truncatesthearray,ifit'soverbatchSizebuffer.length=batchSize;

//turnsonthegate,pausingthestream

gate.next(false);

batchSizeCounter=0;

}

});

https://goo.gl/DMOqBA

Page 175: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

letbuffer=getWebSocket()

.bufferTime(1000);

letgate=newBehaviorSubject(true);

letbatchSize=50;

letbatchSizeCounter=0;

letresults=gate$

.switchMap(enabled=>enabled?buffer:Observable.never())

.do(buffer=>{

batchSizeCounter+=buffer.length;

if(batchSizeCounter>=batchSize){

//truncatesthearray,ifit'soverbatchSizebuffer.length=batchSize;

//turnsonthegate,pausingthestream

gate.next(false);

batchSizeCounter=0;

}

});

https://goo.gl/DMOqBA

Page 176: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

letbuffer=getWebSocket()

.bufferTime(1000);

letgate=newBehaviorSubject(true);

letbatchSize=50;

letbatchSizeCounter=0;

letresults=gate$

.switchMap(enabled=>enabled?buffer:Observable.never())

.do(buffer=>{

batchSizeCounter+=buffer.length;

if(batchSizeCounter>=batchSize){

//truncatesthearray,ifit'soverbatchSizebuffer.length=batchSize;

//turnsonthegate,pausingthestream

gate.next(false);

batchSizeCounter=0;

}

});

https://goo.gl/DMOqBA

Page 177: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

letbuffer=getWebSocket()

.bufferTime(1000);

letgate=newBehaviorSubject(true);

letbatchSize=50;

letbatchSizeCounter=0;

letresults=gate$

.switchMap(enabled=>enabled?buffer:Observable.never())

.do(buffer=>{

batchSizeCounter+=buffer.length;

if(batchSizeCounter>=batchSize){

//truncatesthearray,ifit'soverbatchSizebuffer.length=batchSize;

//turnsonthegate,pausingthestream

gate.next(false);

batchSizeCounter=0;

}

});

https://goo.gl/DMOqBA

Page 178: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

letbuffer=getWebSocket()

.bufferTime(1000);

letgate=newBehaviorSubject(true);

letbatchSize=50;

letbatchSizeCounter=0;

letresults=gate$

.switchMap(enabled=>enabled?buffer:Observable.never())

.do(buffer=>{

batchSizeCounter+=buffer.length;

if(batchSizeCounter>=batchSize){

//truncatesthearray,ifit'soverbatchSizebuffer.length=batchSize;

//turnsonthegate,pausingthestream

gate.next(false);

batchSizeCounter=0;

}

});

https://goo.gl/DMOqBA

Page 179: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

letbuffer=getWebSocket()

.bufferTime(1000);

letgate=newBehaviorSubject(true);

letbatchSize=50;

letbatchSizeCounter=0;

letresults=gate$

.switchMap(enabled=>enabled?buffer:Observable.never())

.do(buffer=>{

batchSizeCounter+=buffer.length;

if(batchSizeCounter>=batchSize){

//truncatesthearray,ifit'soverbatchSizebuffer.length=batchSize;

//turnsonthegate,pausingthestream

gate.next(false);

batchSizeCounter=0;

}

});

https://goo.gl/DMOqBA

Page 180: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

letbuffer=getWebSocket()

.bufferTime(1000);

letgate=newBehaviorSubject(true);

letbatchSize=50;

letbatchSizeCounter=0;

letresults=gate$

.switchMap(enabled=>enabled?buffer:Observable.never())

.do(buffer=>{

batchSizeCounter+=buffer.length;

if(batchSizeCounter>=batchSize){

//truncatesthearray,ifit'soverbatchSizebuffer.length=batchSize;

//turnsonthegate,pausingthestream

gate.next(false);

batchSizeCounter=0;

}

});

https://goo.gl/DMOqBA

Page 181: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Works for low-volume queries too

Page 182: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Raven

Page 183: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

RavenSweet Christmas

Page 184: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

improved debugging, testing, and InfoSec

Page 185: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Netflix loves Rx

Page 186: Real-time Insights, powered by Reactive Programming

Jay Phelps | @_jayphelps

Rx is powerful, cross-platform

Page 187: Real-time Insights, powered by Reactive Programming

Thanks!

@_jayphelps