reactive streams in the web (jug saxony)akka streams backpressure declarative programming...

76
Reactive Streams in the Web Florian Stefan | eBay Classifieds Group | JUG Saxony 2017

Upload: others

Post on 25-May-2020

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ReactiveStreamsintheWebFlorianStefan|eBayClassifiedsGroup|JUGSaxony2017

Page 2: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

WhoamI?

§ FlorianStefan§mobile.de (eBay ClassifiedsGroup)§ https://ebaytech.berlin/§ [email protected] |@f_s_t_e_f_a_n§ https://github.com/florian-stefan/

Page 3: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Contents

1) Motivation:DistributedSystems2) ReactiveStreamswithReactor3) ProgressiveHTMLRenderingwith Spring5

It‘s about concepts rather than details!

Page 4: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Whyarewehere?It’sadistributedworld!

Page 5: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

BFFBFF

ServiceBServiceB

ServiceAServiceA

Whyarewehere?

ServiceA ServiceB

BFF

Page 6: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

HTTP

Howarewedoingthis?

ServiceA

Database

Topic ServiceB Topic

BFF

Page 7: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

HTTP

Howarewedoingthis?

ServiceA

Database

Topic ServiceB Topic

BFF

Event-DrivenSystems

ConcurrentRemoteCalls

Page 8: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

HTMLRendering

Server-SideRendering

AJAX

BFF

Widget Widget

Widget

Widget Widget

ConcurrentRemoteCalls

Page 9: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Server-SideRendering§ TimeToFirstByte§ Prerendering /Caching

HTMLRendering

Page 10: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

AJAX§ Head-of-lineblocking§ MultiplexingwithHTTP/2

HTMLRendering

Page 11: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Canwedobetter?Howexpensivewillitbe?

Page 12: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

TheReactiveLandscape

Page 13: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ConcurrentRemoteCalls

Event-DrivenSystems

DistributedSystems

ReactiveSystems

ReactiveManifesto

ReactiveStreams

ReactiveExtensions

MarbleDiagrams

RxJava

Reactor

Akka Streams

Backpressure

DeclarativeProgramming

Higher-OrderFunctions

Page 14: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ConcurrentRemoteCalls

Event-DrivenSystems

DistributedSystems

ReactiveSystems

ReactiveManifesto

ReactiveStreams

ReactiveExtensions

MarbleDiagrams

RxJava

Reactor

Akka Streams

Backpressure

DeclarativeProgramming

Higher-OrderFunctions

Page 15: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

TheReactiveManifesto

Page 16: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Responsive

Elastic Resilient

MessageDriven

ReacttoUser

ReacttoLoad ReacttoFailure

ReacttoEvents

Page 17: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ConcurrentRemoteCalls

Event-DrivenSystems

DistributedSystems

ReactiveSystems

ReactiveManifesto

ReactiveStreams

ReactiveExtensions

MarbleDiagrams

RxJava

Reactor

Akka Streams

Backpressure

DeclarativeProgramming

Higher-OrderFunctions

Page 18: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

public interface Somethings {

Something loadById(int id);

}

ReactiveExtensions

API

Service

something

Page 19: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ReactiveExtensions

API

Service

something

public Something loadById(int id) {

return somethings.loadById(id);

}

Page 20: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ReactiveExtensions

API

Service

something

Service API Resource

NetworkBoundary

Page 21: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ReactiveExtensions

API

Service

something

public CompletableFuture<Something> loadById(int id) {

return supplyAsync(() -> somethings.loadById(id), executor);

}

Page 22: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ReactiveExtensions

API

Service

something

NetworkBoundary

ResourceService API

Page 23: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

public interface Somethings {

void loadById(int id, BiConsumer<Exception, Something> callback);

}

ReactiveExtensions

API

Service

something

Page 24: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

public CompletableFuture<Something> loadById(int id) {

CompletableFuture<Something> eventualSomething =

new CompletableFuture<>();

somethings.loadById(id, (error, something) -> {

if (error != null) {

eventualSomething.completeExceptionally(error);

} else {

eventualSomething.complete(something);

}

});

return eventualSomething;

}

ReactiveExtensions

API

Service

something

Page 25: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

NetworkBoundary

ResourceService API

ReactiveExtensions

API

Service

something

Page 26: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ReactiveExtensions

CompletableFuture<T>

representsanalreadyscheduledtaskcompletesonlyonce

Flux<T>

representsabuildingplan(callerhastosubscribe)emitsmanyvalues

Mono<T>

representsabuildingplan(callerhastosubscribe)emitsatmostonevalue

subscribe { , }�

Page 27: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Operator

Subscriber

Publisher

ReactiveExtensions

map { }

subscribe { }

fromArray { }

[ , , ]

wraps

subscribesto

Page 28: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ReactiveExtensions

Circle[] circles = { Circle.of(BLUE), ... };

Flux.fromArray(circles)

.map(circle -> Square.of(circle.getColor()))

.subscribe(...);

.log()

[main] INFO - | onSubscribe()

[main] INFO - | ?

[main] INFO - | onNext(Square(BLUE))

[main] INFO - | onNext(Square(YELLOW))

[main] INFO - | onNext(Square(GREEN))

[main] INFO - | onComplete()

Page 29: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ConcurrentRemoteCalls

Event-DrivenSystems

DistributedSystems

ReactiveSystems

ReactiveManifesto

ReactiveStreams

ReactiveExtensions

MarbleDiagrams

RxJava

Reactor

Akka Streams

Backpressure

DeclarativeProgramming

Higher-OrderFunctions

Page 30: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Concurrency

subscribe { }

CallingThread

map { }

Page 31: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Concurrency

subscribe { }

CallingThread Scheduler

subscribeOn { }

map { }

Page 32: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Concurrency

subscribe { }

CallingThread Scheduler

flatMap { }

subscribeOn { }

Page 33: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Concurrency

Flux.fromIterable(ids)

API

Service

something

Scheduler scheduler =

Schedulers.newParallel("pool", 8);

[main] INFO - onSubscribe()

.flatMap(id -> Mono.just(id).map(somethings::loadById)

.subscribeOn(scheduler))

.log()

.subscribe();[main] INFO - ?

[pool-1] INFO - onNext(Something(id=1))

[pool-2] INFO - onNext(Something(id=2))

[pool-3] INFO - onNext(Something(id=3))

[pool-3] INFO - onComplete()

Page 34: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ConcurrentRemoteCalls

Event-DrivenSystems

DistributedSystems

ReactiveSystems

ReactiveManifesto

ReactiveStreams

ReactiveExtensions

MarbleDiagrams

RxJava

Reactor

Akka Streams

Backpressure

DeclarativeProgramming

Higher-OrderFunctions

Page 35: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

Page 36: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

subscribe

Page 37: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

Page 38: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

1onNext( )

Page 39: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

onNext( )2

Page 40: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

onNext( )3

Page 41: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

onNext( )4

Page 42: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

onNext( )5

Page 43: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

5

Backpressure

Publisher Subscriber

onNext( )

ExecutorService executorService =

new ThreadPoolExecutor(

nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(capacity)

);

ids.stream()

.map(id -> executorService

.submit(() -> somethings.loadById(id)))

.collect(toList())

.stream()

.map(waitForSomething())

.forEach(handleSomething());

java.util.concurrent.RejectedExecutionException:

Task rejected from ThreadPoolExecutor [

Running, pool size = 2, active threads = 2,

queued tasks = 4, completed tasks = 0

]

Page 44: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

Page 45: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

subscribe

Page 46: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

Page 47: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

request(3)

Page 48: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

Page 49: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

1onNext( )

Page 50: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

onNext( )2

Page 51: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

onNext( )3

Page 52: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

Page 53: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

request(2)

Page 54: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

Page 55: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

onNext( )4

Page 56: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

Publisher Subscriber

onNext( )5

Page 57: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

5

Backpressure

Publisher Subscriber

onNext( )

ExecutorService executorService =

new ThreadPoolExecutor(

nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(capacity)

);

Flux.fromIterable(ids).log()

.flatMap(id -> Mono.just(id).map(somethings::loadById)

.subscribeOn(scheduler), 3)

.doOnNext(handleSomething())

.subscribe();

Scheduler scheduler = Schedulers

.fromExecutorService(executorService);

[main] INFO - | onSubscribe()

[main] INFO - | request(3)

[main] INFO - | onNext(1)

[main] INFO - | onNext(2)

[main] INFO - | onNext(3)

[pool-1] INFO - | request(1)

[pool-1] INFO - | onNext(4)

[pool-2] INFO - | request(1)

[pool-2] INFO - | onNext(5)

[pool-2] INFO - | onComplete()

Page 58: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Backpressure

HTTP

ServiceA

Database

Topic ServiceB Topic

BFF

Page 59: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ProgressiveHTMLRenderingProgressive

Page 60: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ProgressiveHTMLRendering

Transfer-Encoding:chunked

BFF

Widget Widget

Widget

Widget Widget

ConcurrentRemoteCalls

Page 61: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ProgressiveHTMLRendering

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-webflux</artifactId>

</dependency>

Page 62: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ProgressiveHTMLRendering

@SpringBootApplication

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);}

}

curl -i -N localhost:8080/hello

@RestController

@GetMapping(value = "hello")

public Flux<String> sayHello() {

return Flux.interval(Duration.ofMillis(500)).map(tick -> "Hello\n");}

HTTP/1.1 200

Content-Type: text/plain

Transfer-Encoding: chunked

Hello

Hello

Hello

Hello

Page 63: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

BakinganHTMLstream

Page 64: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Spring5WebClient NetworkBoundary

WidgetServerWidgetService WebClient

WebClient.create().get()

.uri("http://widget-server")

.retrieve()

.bodyToFlux(String.class)

.subscribe(this::onNext);

Page 65: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

HTMLRendering

HTTPRequest

AccepterThread

HTTPResponse

ConnectionQueue RequestThread

Model

TemplateHttpResponse.getWriter()

OutputBuffer

Page 66: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Processor<T, DataBuffer>

Model

Reactive-FriendlyTemplateEngine

Flux<T>

Template

th:each="..."requests

DataBuffer

ReactiveWebServer

subscribes

HTMLrendered as values are published

Page 67: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ProgressiveHTMLRendering

Processor

Subscriber

Publisher Spring5WebClient

Reactive-FriendlyThymeleaf View

ReactiveWebServer

Page 68: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

URI uri = ...

String name = ...

Mono<Pagelet> pageletMono = webClient.get().uri(uri).exchange()

.flatMap(res -> res.bodyToMono(String.class))

.map(body -> new Pagelet(name, body));

List<Mono<Pagelet>> pageletMonos = ...;

... = Flux.merge(pageletMonos);

ProgressiveHTMLRendering

Publisher Spring5WebClient

Page 69: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

@GetMapping(value = "/widgets")

public String widgets(Model model) {

List<String> pageletNames = widgetService.getPageletNames();

Flux<Pagelet> pagelets = widgetService.loadPagelets();

model.addAttribute("pageletNames", pageletNames);

model.addAttribute("pagelets", new ReactiveDataDriverContextVariable(pagelets, 1));

return "widgets";

}

ProgressiveHTMLRendering

Processor ReactiveThymeleaf View

Page 70: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

<article th:each="pageletName: ${pageletNames}" class="...">

<section class="...">

<div th:id="${pageletName}" class="...">

<div class="...">...</div>

</div>

</section>

</article>

ProgressiveHTMLRendering

Processor ReactiveThymeleaf View

Page 71: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

<script th-inline="javascript" th:each="pagelet : ${pagelets}">

(function() {var element = document.getElementById("[[${pagelet.name}]]");

if(element) {element.innerHTML = "[(${pagelet.content})]";

}

})();

</script>

ProgressiveHTMLRendering

Processor ReactiveThymeleaf View

Page 72: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Doesitwork?

Page 73: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

ProgressiveHTMLRendering

Page 74: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

What‘s more?

§ ColdStreamsvs.HotStreams§ ReactiveDatabaseDrivers§ BackpressureStrategies§ Threadedvs.EventedServerModel§WebSockets andServer-SentEvents

Page 75: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Thankyou!

Page 76: Reactive Streams in the Web (JUG Saxony)Akka Streams Backpressure Declarative Programming Higher-Order Functions Concurrent Remote Calls Event-Driven Systems Distributed Systems Reactive

Questions?