서버 개발자가 바라 본 functional reactive programming with rxjava - springcamp2015

54
서버 개발자가 바라 본 F unctional R eactive P rogramming with RxJava 김대성 http://gmind7.github.io Java Software Developer

Upload: -

Post on 20-Jul-2015

1.290 views

Category:

Software


3 download

TRANSCRIPT

Page 1: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

서버 개발자가 바라 본Functional Reactive Programmingwith RxJava

김대성

http://gmind7.github.io

Java Software Developer

Page 2: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

2

Page 3: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

3

Page 4: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

4

int a = 0;

int b = a*1;

int c = a*1;

int d = b*c;

.println(d) // 0

d

a

b c

d

b

a

Machine1

c

Machine2Actor Model

Functional Reactive Programming e.g

a = 2

.println(d) // ?

// b=2, c=2, d=4

Page 5: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

5

eXchange programming paradigm

Page 6: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

6

FP RPFRP

Functional Reactive Programming 이란?

Page 7: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

7

Page 8: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

8

COMPOSABLE FUNCTIONS

REACTIVELY APPLIED

d

b

ca

Page 9: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

9

RxJava

getData();

Calling Thread

Thread Pool

Callback Thread

Observable<Data> Public

Page 10: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

10

RxJava

EVENT ITERABLE (PULL) OBSERVABLE (PUSH)

Retrieve Data onNext(T)

Discover Error onError(Exception)

Complete onCompleted()

PUSH 4 3 2 1 …..

Page 11: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

11

RxJava

>> 4 3 2 1 ….. >>

ObserverObservable

PUSH

Page 12: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

12

RxJava Hello, World!

Observable

데이터 발행 (PUSH) 하기

>> 4 3 2 1 ….. >>PUSH

Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {

@Overridepublic void call(Subscriber<? super String> subscriber) {

subscriber.onNext("Hello, world!"); // 데이터 PUSH … nextsubscriber.onCompleted(); // 데이터 PUSH 이제 그만(완료) 할게..

}}

);

Page 13: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

13

RxJava

Observer

Hello, World!

PUSH 될 데이터 구독(소비) 계획 하기

>> 4 3 2 1 ….. >>

Subscriber<String> subscriber = new Subscriber<String>() {@Override // 구독 계획public void onNext(String s) { System.out.println("onNext:" + s); }@Override // 에러 계획public void onError(Throwable e) { System.out.println("onError:"+e.getMessage()); }@Override // 완료 계획public void onCompleted() { System.out.println("onComplated"); }

};

Page 14: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

14

RxJava Hello, World!

// 2. PUSH 될 데이터 구독 계획Subscriber<String> subscriber = new Subscriber<String>() {……

// 3. 구독자가 가입 되면 데이터 발행 -> 구독 (Run)observable.subscribe(subscriber);

// 1. PUSH 데이터 생성 (Async)Observable<String> observable = Observable.create( ……

Page 15: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

15

RxJava Hello, World!

// java 7Observable.just("Hello, world!").subscribe(new Action1<String>() {

@Overridepublic void call(String s) {

System.out.println(s);}

});

// java 8Observable.just("Hello, world!").subscribe(System.out::println);

// Outputs// Hello, world!

Page 16: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

16

- Create

- Defer- Empty / Never ..- From- Interval- Just- Range- Repeat- Start- Timer…..

- And / Then / When

- CombineLatest- Join- Merge- StartWith- Switch- Map / FlatMap- Zip- Filter- IgnoreElemets- Last

…..

- Delay

- Do- Materialize- Dematerialize- ObserveOn- Serialize- Subscribe- SubscribeOn- TimeInterval- Timeout…..

Page 17: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

17

Page 18: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

18

Page 19: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

19

@RequestMapping(value="/callable", method = RequestMethod.GET)public Callable<Object> callableShowAll() {

Callable<Object> callable = () -> accountService.findAll();return callable;

}

@RequestMapping(value="/rxjava", method = RequestMethod.GET)public DeferredResult<Object> rxJavaShowAll() {

DeferredResult<Object> deferredResult = new DeferredResult<>(5000L);Observable<List<Account>> resources = accountService.rxFindAll();resources.subscribe(response -> {

deferredResult.setResult(response);});return deferredResult;

}

RxJava +

Page 20: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

20

1 2 3 4 5 6 …recommendService

.requestRecommends(id)

RxJava +

Page 21: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

21

@RequestMapping(value="/{id}", method = RequestMethod.GET)public DeferredResult<Object> showYourStore(@PathVariable("id") Long id) {

DeferredResult<Object> deferredResult = new DeferredResult<>();Observable<Recommend> recommendRx = recommend.requestRecommends(id);…..deferredResult.setResult(response);

return deferredResult;

RxJava +

Page 22: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

22

RxJava + public Observable<Recommend> requestRecommends(long accountId) {return Observable.from(RxNetty.createHttpGet("http://localhost:19080" + "/rxjava/recommend/" +

accountId).flatMap(response -> response.getContent().map(content ->

content.toString(Charset.defaultCharset()))).map(data -> new Gson().fromJson(new String(data), Recommend[].class))

.toBlocking().single());}

Page 23: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

23

1 2 3 4 5 6 …recommendService

.requestRecommends(id)

1 2 3 4 5

unsubscribe

.take(5)

RxJava +

Page 24: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

24

@RequestMapping(value="/{id}", method = RequestMethod.GET)public DeferredResult<Object> showYourStore(@PathVariable("id") Long id) {

DeferredResult<Object> deferredResult = new DeferredResult<>();Observable<Recommend> recommendRx = recommend.requestRecommends(id);recommendRx

.take(5)…..deferredResult.setResult(response);

return deferredResult;

RxJava +

Page 25: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

25

1 2 6 …recommendService

.requestRecommends(id)

1 2.take(5)

.flatMap() 1 2

3

3

3

4

4

4

5

5

5

RxJava +

unsubscribe

Page 26: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

26

@RequestMapping(value="/{id}", method = RequestMethod.GET)public DeferredResult<Object> showYourStore(@PathVariable("id") Long id) {

DeferredResult<Object> deferredResult = new DeferredResult<>();Observable<Recommend> recommendRx = recommend.requestRecommends(id);recommendRx

.take(3)

.flatMap(recommend -> {…….

}…..deferredResult.setResult(response);

return deferredResult;

RxJava +

Page 27: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

27

1 2 3 4 5 6 …recommendService

.requestRecommends(id)

1 2 3 4 5.take(5)

.flatMap()

goodsMetaInfo()

1 2 3 4 5

1

RxJava +

unsubscribe

Page 28: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

28

……………….flatMap(recommend -> {// async 1Observable<GoodsMetaInfo> goodsMetaInfo = goodsMetaInfo.findOne(recommend.id())

……..

RxJava +

Page 29: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

29

1 2 3 4 5 6 …recommendService

.requestRecommends(id)

1 2 3 4 5.take(5)

.flatMap()

goodsMetaInfo()

.map()

1 2 3 4 5

1

1

RxJava +

unsubscribe

Page 30: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

30

……………….flatMap(recommend -> {// async 1Observable<GoodsMetaInfo> goodsMetaInfo = goodsMetaInfo.findOne(recommend.id()).map(x -> { // 출시 1개월 이내 상품에는 [New] 타이틀 추가boolean isNewTitle = x.createDate.isAfter(LocalDateTime.now().minusMonths(1));if (isNewTitle) {x.setTitle("[New] " + x.getTitle());

}return x;

});…….….

})……..

RxJava +

Page 31: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

31

1 2 3 4 5 6 …recommendService

.requestRecommends(id)

1 2 3 4 5.take(5)

.flatMap()

goodsMetaInfo()

goodsRating()

.map()

1 2 3 4 5

1

1

1

RxJava +

unsubscribe

Page 32: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

32

RxJava ……………….flatMap(recommend -> {// async 1Observable<GoodsMetaInfo> goodsMetaInfo = goodsMetaInfo.findOne(recommend.id()).map(x -> {

boolean isNewTitle = x.createDate.isAfter(LocalDateTime.now().minusMonths(1));if (isNewTitle) {

x.setTitle("[New] " + x.getTitle());}return x;

});// async 2Observable<GoodsRating> goodsRating = goodsRating.findOne(recommend.id());…….….

})……..

Page 33: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

33

1 2 3 4 5 6 …recommendService

.requestRecommends(id)

1 2 3 4 5.take(5)

.flatMap()

goodsMetaInfo()

goodsRating()

.map()

1 2 3 4 5

1

1

.zip()

1

1

RxJava

unsubscribe

Page 34: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

34

……………….flatMap(recommend -> {Observable<GoodsMetaInfo> goodsMetaInfo = goodsMetaInfo.findOne(recommend.id()).map(x -> {

boolean isNewTitle = x.createDate.isAfter(LocalDateTime.now().minusMonths(1));if (isNewTitle) {

x.setTitle("[New] " + x.getTitle());}return x;

});Observable<GoodsRating> goodsRating = goodsRating.findOne(recommend.id());// async 3return Observable.zip(goodsMetaInfo, goodsRating, (x, y) -> {Map<String, Object> map = Maps.newHashMap();map.put("recommend", recommend);map.put("goods", x);map.put("rating", y);return map;

});})……..

RxJava +

Page 35: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

35

1 2 3 4 5 6 …recommendService

.requestRecommends(id)

1 2 3 4 5

unsubscribe

.take(5)

.flatMap()

goodsMetaInfo()

goodsRating()

.map()

1 2 3 4 5

1

1

.zip()

1

1

.toList() 1 2 3 4 5

RxJava +

Page 36: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

36

@RequestMapping(value="/{id}", method = RequestMethod.GET)public DeferredResult<Object> showYourStore(@PathVariable("id") Long id) {

DeferredResult<Object> deferredResult = new DeferredResult<>();Observable<Recommend> recommendRx = recommend.requestRecommends(id);recommendRx

.take(3)

.flatMap(recommend -> { ……

}).toList()…..

return deferredResult;

RxJava +

Page 37: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

37

@RequestMapping(value="/{id}", method = RequestMethod.GET)public DeferredResult<Object> showYourStore(@PathVariable("id") Long id) {DeferredResult<Object> deferredResult = new DeferredResult<>();Observable<Recommend> recommendRx = recommend.requestRecommends(id);recommendRx.take(3).flatMap(recommend -> {

……..……..})

.toList()

.timeout(5L, TimeUnit.SECONDS)

.subscribe(response -> {deferredResult.setResult(response);

}, error -> {deferredResult.setErrorResult(error);

}, () -> {});

return deferredResult;

RxJava +

Page 38: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

38

@RequestMapping(value="/{id}", method = RequestMethod.GET)public DeferredResult<Object> showYourStore(@PathVariable("id") Long id) {DeferredResult<Object> deferredResult = new DeferredResult<>();Observable<Recommend> recommendRx = recommend.requestRecommends(id);recommendRx.take(3).flatMap(recommend -> {

……..……..})

.toList()

.timeout(5L, TimeUnit.SECONDS)

.subscribe(response -> {

deferredResult.setResult(response);}, error -> {deferredResult.setErrorResult(error);

}, () -> {});

return deferredResult;

RxJava +

Page 39: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

39

Page 40: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

40

Page 41: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

41

……………….flatMap(recommend -> {Observable<GoodsMetaInfo> goodsMetaInfo = goodsMetaInfo.findOne(recommend.id())….subscribeOn(Schedulers.computation()); Observable<GoodsRating> goodsRating = goodsRating.findOne(recommend.id())….subscribeOn(Schedulers.computation());return Observable.zip(goodsMetaInfo, goodsRating, (x, y) -> {…return map;

}).subscribeOn(Schedulers.computation());})……..

RxJava +

Page 42: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

42

ERROR

Page 43: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

43

@RequestMapping(value="/{id}", method = RequestMethod.GET)public DeferredResult<Object> showYourStore(@PathVariable("id") Long id) {DeferredResult<Object> deferredResult = new DeferredResult<>();Observable<Recommend> recommendRx = recommend.requestRecommends(id);recommendRx.take(3).flatMap(recommend -> {

Observable<GoodsMetaInfo> goodsMetaInfo = goodsMetaInfo….…Observable<GoodsRating> goodsRating = goodsRating……})

.toList()

.timeout(5L, TimeUnit.SECONDS)

.subscribe(response -> {deferredResult.setResult(response);

}, error -> {deferredResult.setErrorResult(error);

}, () -> {});

return deferredResult;

RxJava +

Page 44: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

44

RxJava +

request

Netty

tcpwrite

response

tcpwrite

public Channel…

@Overridepublic void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {Account message = new Account(1);Observable<Object> observable = clientReqHandler.request(ctx.channel(), message);observable.subscribe(response -> {ctx.channel().writeAndFlush(response);

});}

?tcpread

public void …

Page 45: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

45

RxJava + Nettypublic class ClientRequestHandler extends SimpleChannelInboundHandler<Object> {private final ConcurrentHashMap QUEUE = new ConcurrentHashMap<String, Subscriber<?>>;

public ClientRequestHandler(){}

Page 46: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

46

RxJava + Nettypublic Observable<Object> request(final Channel channel, final Object message) {return Observable.<Object>create(suscriber -> {

this.QUEUE.put("requestId", suscriber);channel.writeAndFlush(message);

}).timeout(5L, TimeUnit.SECONDS).finallyDo(() -> queue.remove("requestId")});

};

@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, Object object) throws Exception {Subscriber subscriber = (Subscriber)this.QUEUE.remove("requestId");if(subscriber==null) return;subscriber.onNext(object);subscriber.onCompleted();

}

Page 47: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

47

RxJava + Netty

@Overridepublic void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {Account message = new Account(1);Observable<Object> observable = clientReqHandler.request(ctx.channel(), message);observable.subscribe(response -> {ctx.channel().writeAndFlush(response);

});}

request1

tcpwrite

response1

tcpwrite

public void …tcpread

public void …

Page 48: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

48

Page 49: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

49

Page 50: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

50

Page 51: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

51

Page 52: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

OOP

CACHE

RDBMS

1995 2015

HADOOP

NOSQL

FP, RX, FRP …

지금은 POLYGLOT 시대…

Page 53: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

53

http://www.manning.com/blackheathhttp://www.slideshare.net/InfoQ/functional-reactive-programming-in-the-netflix-apihttps://youtu.be/-P28LKWTzrITowards Reactive Programming for Object-oriented Applications.pdfhttp://www.slideshare.net/misgod/functional-41887638http://ent.hankyung.com/news/app/newsview.php?aid=2014112839734

Page 54: 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

감사합니다