SlideShare une entreprise Scribd logo
1  sur  54
Télécharger pour lire hors ligne
서버 개발자가 바라 본
Functional Reactive Programming
with RxJava
김대성
http://gmind7.github.io
Java Software Developer
2
3
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
5
eXchange programming paradigm
6
FP RPFRP
Functional Reactive Programming 이란?
7
8
COMPOSABLE FUNCTIONS
REACTIVELY APPLIED
d
b
ca
9
RxJava
getData();
Calling Thread
Thread Pool
Callback Thread
Observable<Data>Public
10
RxJava
EVENT ITERABLE (PULL) OBSERVABLE (PUSH)
Retrieve Data onNext(T)
Discover Error onError(Exception)
Complete onCompleted()
PUSH 4 3 2 1 …..
11
RxJava
>> 4 3 2 1 ….. >>
ObserverObservable
PUSH
12
RxJava Hello, World!
Observable
데이터 발행 (PUSH) 하기
>> 4 3 2 1 ….. >>
PUSH
Observable<String> observable = Observable.create(
new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello, world!"); // 데이터 PUSH … next
subscriber.onCompleted(); // 데이터 PUSH 이제 그만(완료) 할게..
}
}
);
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"); }
};
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( ……
15
RxJava Hello, World!
// java 7
Observable.just("Hello, world!").subscribe(new Action1<String>() {
@Override
public void call(String s) {
System.out.println(s);
}
});
// java 8
Observable.just("Hello, world!").subscribe(System.out::println);
// Outputs
// Hello, world!
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
…..
17
18
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 +
20
1 2 3 4 5 6 …
recommendService
.requestRecommends(id)
RxJava +
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 +
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());
}
23
1 2 3 4 5 6 …
recommendService
.requestRecommends(id)
1 2 3 4 5
unsubscribe
.take(5)
RxJava +
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 +
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
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 +
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
28
………………
.flatMap(recommend -> {
// async 1
Observable<GoodsMetaInfo> goodsMetaInfo = goodsMetaInfo.findOne(recommend.id())
……..
RxJava +
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
30
………………
.flatMap(recommend -> {
// async 1
Observable<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 +
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
32
RxJava
………………
.flatMap(recommend -> {
// async 1
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;
});
// async 2
Observable<GoodsRating> goodsRating = goodsRating.findOne(recommend.id());
…….
….
})
……..
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
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 3
return 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 +
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 +
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 +
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 +
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 +
39
40
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 +
42
ERROR
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 +
44
RxJava +
request
Netty
tcpwrite
response
tcpwrite
public Channel…
@Override
public 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…
45
RxJava + Netty
public class ClientRequestHandler extends SimpleChannelInboundHandler<Object> {
private final ConcurrentHashMap QUEUE
= new ConcurrentHashMap<String, Subscriber<?>>;
public ClientRequestHandler(){
}
46
RxJava + Netty
public 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")});
};
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object
object) throws Exception {
Subscriber subscriber = (Subscriber)this.QUEUE.remove("requestId");
if(subscriber==null) return;
subscriber.onNext(object);
subscriber.onCompleted();
}
47
RxJava + Netty
@Override
public 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…
48
49
50
51
OOP
CACHE
RDBMS
1995 2015
HADOOP
NOSQL
FP, RX, FRP …
지금은 POLYGLOT 시대…
53
http://www.manning.com/blackheath
http://www.slideshare.net/InfoQ/functional-reactive-programming-in-the-netflix-api
https://youtu.be/-P28LKWTzrI
Towards Reactive Programming for Object-oriented Applications.pdf
http://www.slideshare.net/misgod/functional-41887638
http://ent.hankyung.com/news/app/newsview.php?aid=2014112839734
감사합니다

Contenu connexe

Tendances

윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019devCAT Studio, NEXON
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVCIndicThreads
 
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018devCAT Studio, NEXON
 
[0119 박민근] 기술 면접시 자주 나오는 문제들(ver 2013)
[0119 박민근] 기술 면접시 자주 나오는 문제들(ver 2013)[0119 박민근] 기술 면접시 자주 나오는 문제들(ver 2013)
[0119 박민근] 기술 면접시 자주 나오는 문제들(ver 2013)MinGeun Park
 
홍성우, 내가 만든 언어로 게임 만들기, NDC2017
홍성우, 내가 만든 언어로 게임 만들기, NDC2017홍성우, 내가 만든 언어로 게임 만들기, NDC2017
홍성우, 내가 만든 언어로 게임 만들기, NDC2017devCAT Studio, NEXON
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템QooJuice
 
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버Heungsub Lee
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011Esun Kim
 
C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2Chris Ohk
 
카카오톡으로 여친 만들기 2013.06.29
카카오톡으로 여친 만들기 2013.06.29카카오톡으로 여친 만들기 2013.06.29
카카오톡으로 여친 만들기 2013.06.29Taehoon Kim
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화Seungmo Koo
 
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스Dan Kang (강동한)
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at NetflixBrendan Gregg
 
Redux Toolkit - Quick Intro - 2022
Redux Toolkit - Quick Intro - 2022Redux Toolkit - Quick Intro - 2022
Redux Toolkit - Quick Intro - 2022Fabio Biondi
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
 
Scaling Django with gevent
Scaling Django with geventScaling Django with gevent
Scaling Django with geventMahendra M
 
임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013devCAT Studio, NEXON
 
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)Heungsub Lee
 

Tendances (20)

윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVC
 
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
 
[0119 박민근] 기술 면접시 자주 나오는 문제들(ver 2013)
[0119 박민근] 기술 면접시 자주 나오는 문제들(ver 2013)[0119 박민근] 기술 면접시 자주 나오는 문제들(ver 2013)
[0119 박민근] 기술 면접시 자주 나오는 문제들(ver 2013)
 
홍성우, 내가 만든 언어로 게임 만들기, NDC2017
홍성우, 내가 만든 언어로 게임 만들기, NDC2017홍성우, 내가 만든 언어로 게임 만들기, NDC2017
홍성우, 내가 만든 언어로 게임 만들기, NDC2017
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템
 
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011
 
C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2C++17 Key Features Summary - Ver 2
C++17 Key Features Summary - Ver 2
 
카카오톡으로 여친 만들기 2013.06.29
카카오톡으로 여친 만들기 2013.06.29카카오톡으로 여친 만들기 2013.06.29
카카오톡으로 여친 만들기 2013.06.29
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
 
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at Netflix
 
Redux Toolkit - Quick Intro - 2022
Redux Toolkit - Quick Intro - 2022Redux Toolkit - Quick Intro - 2022
Redux Toolkit - Quick Intro - 2022
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
 
GDB Rocks!
GDB Rocks!GDB Rocks!
GDB Rocks!
 
Scaling Django with gevent
Scaling Django with geventScaling Django with gevent
Scaling Django with gevent
 
임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013임태현, 게임 서버 디자인 가이드, NDC2013
임태현, 게임 서버 디자인 가이드, NDC2013
 
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
 

En vedette

Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streamsmattpodwysocki
 
[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍NAVER D2
 
Functional Reactive Programming With RxSwift
Functional Reactive Programming With RxSwiftFunctional Reactive Programming With RxSwift
Functional Reactive Programming With RxSwift선협 이
 
Functional Reactive Programming with RxJS
Functional Reactive Programming with RxJSFunctional Reactive Programming with RxJS
Functional Reactive Programming with RxJSstefanmayer13
 
RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015Ben Lesh
 
혁신적인 웹컴포넌트 라이브러리 - Polymer
혁신적인 웹컴포넌트 라이브러리 - Polymer혁신적인 웹컴포넌트 라이브러리 - Polymer
혁신적인 웹컴포넌트 라이브러리 - PolymerJae Sung Park
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
Module, AMD, RequireJS
Module, AMD, RequireJSModule, AMD, RequireJS
Module, AMD, RequireJS偉格 高
 
RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리
RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리
RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리Soyeon Kim
 
System webpack-jspm
System webpack-jspmSystem webpack-jspm
System webpack-jspmJesse Warden
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
React in Native Apps - Meetup React - 20150409
React in Native Apps - Meetup React - 20150409React in Native Apps - Meetup React - 20150409
React in Native Apps - Meetup React - 20150409Minko3D
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesomeAndrew Hull
 
맛만 보자 액터 모델이란
맛만 보자 액터 모델이란 맛만 보자 액터 모델이란
맛만 보자 액터 모델이란 jbugkorea
 
DEVOPS 에 대한 전반적인 소개 및 자동화툴 소개
DEVOPS 에 대한 전반적인 소개 및 자동화툴 소개DEVOPS 에 대한 전반적인 소개 및 자동화툴 소개
DEVOPS 에 대한 전반적인 소개 및 자동화툴 소개태준 문
 
DevOps와 자동화
DevOps와 자동화DevOps와 자동화
DevOps와 자동화DONGSU KIM
 
Ksug2015 jpa5 스프링과jpa
Ksug2015 jpa5 스프링과jpaKsug2015 jpa5 스프링과jpa
Ksug2015 jpa5 스프링과jpaYounghan Kim
 
Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑Younghan Kim
 

En vedette (20)

Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
 
[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍[1B4]안드로이드 동시성_프로그래밍
[1B4]안드로이드 동시성_프로그래밍
 
Functional Reactive Programming With RxSwift
Functional Reactive Programming With RxSwiftFunctional Reactive Programming With RxSwift
Functional Reactive Programming With RxSwift
 
Functional Reactive Programming with RxJS
Functional Reactive Programming with RxJSFunctional Reactive Programming with RxJS
Functional Reactive Programming with RxJS
 
RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015
 
혁신적인 웹컴포넌트 라이브러리 - Polymer
혁신적인 웹컴포넌트 라이브러리 - Polymer혁신적인 웹컴포넌트 라이브러리 - Polymer
혁신적인 웹컴포넌트 라이브러리 - Polymer
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
Module, AMD, RequireJS
Module, AMD, RequireJSModule, AMD, RequireJS
Module, AMD, RequireJS
 
RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리
RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리
RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리
 
Angular2 ecosystem
Angular2 ecosystemAngular2 ecosystem
Angular2 ecosystem
 
System webpack-jspm
System webpack-jspmSystem webpack-jspm
System webpack-jspm
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
React in Native Apps - Meetup React - 20150409
React in Native Apps - Meetup React - 20150409React in Native Apps - Meetup React - 20150409
React in Native Apps - Meetup React - 20150409
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
맛만 보자 액터 모델이란
맛만 보자 액터 모델이란 맛만 보자 액터 모델이란
맛만 보자 액터 모델이란
 
DEVOPS 에 대한 전반적인 소개 및 자동화툴 소개
DEVOPS 에 대한 전반적인 소개 및 자동화툴 소개DEVOPS 에 대한 전반적인 소개 및 자동화툴 소개
DEVOPS 에 대한 전반적인 소개 및 자동화툴 소개
 
DevOps와 자동화
DevOps와 자동화DevOps와 자동화
DevOps와 자동화
 
Ksug2015 jpa5 스프링과jpa
Ksug2015 jpa5 스프링과jpaKsug2015 jpa5 스프링과jpa
Ksug2015 jpa5 스프링과jpa
 
DevOps with Docker
DevOps with DockerDevOps with Docker
DevOps with Docker
 
Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑
 

Similaire à 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolvedtrxcllnt
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Async Microservices with Twitter's Finagle
Async Microservices with Twitter's FinagleAsync Microservices with Twitter's Finagle
Async Microservices with Twitter's FinagleVladimir Kostyukov
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниStfalcon Meetups
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio
 
10. Kapusta, Stofanak - eGlu
10. Kapusta, Stofanak - eGlu10. Kapusta, Stofanak - eGlu
10. Kapusta, Stofanak - eGluMobCon
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Astrails
 
RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015Constantine Mars
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyBrian Aker
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyBrian Aker
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaRick Warren
 
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"OdessaJS Conf
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...CodiLime
 
What they don't tell you about JavaScript
What they don't tell you about JavaScriptWhat they don't tell you about JavaScript
What they don't tell you about JavaScriptRaphael Cruzeiro
 

Similaire à 서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015 (20)

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Angular2 rxjs
Angular2 rxjsAngular2 rxjs
Angular2 rxjs
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolved
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Async Microservices with Twitter's Finagle
Async Microservices with Twitter's FinagleAsync Microservices with Twitter's Finagle
Async Microservices with Twitter's Finagle
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камни
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
10. Kapusta, Stofanak - eGlu
10. Kapusta, Stofanak - eGlu10. Kapusta, Stofanak - eGlu
10. Kapusta, Stofanak - eGlu
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015RxJava for Android - GDG DevFest Ukraine 2015
RxJava for Android - GDG DevFest Ukraine 2015
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copy
 
Gearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copyGearmam, from the_worker's_perspective copy
Gearmam, from the_worker's_perspective copy
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
CodiLime Tech Talk - Katarzyna Ziomek-Zdanowicz: RxJS main concepts and real ...
 
Spark workshop
Spark workshopSpark workshop
Spark workshop
 
What they don't tell you about JavaScript
What they don't tell you about JavaScriptWhat they don't tell you about JavaScript
What they don't tell you about JavaScript
 

Dernier

Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecturerahul_net
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 

Dernier (20)

Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecture
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 

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

  • 1. 서버 개발자가 바라 본 Functional Reactive Programming with RxJava 김대성 http://gmind7.github.io Java Software Developer
  • 2. 2
  • 3. 3
  • 4. 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
  • 6. 6 FP RPFRP Functional Reactive Programming 이란?
  • 7. 7
  • 10. 10 RxJava EVENT ITERABLE (PULL) OBSERVABLE (PUSH) Retrieve Data onNext(T) Discover Error onError(Exception) Complete onCompleted() PUSH 4 3 2 1 …..
  • 11. 11 RxJava >> 4 3 2 1 ….. >> ObserverObservable PUSH
  • 12. 12 RxJava Hello, World! Observable 데이터 발행 (PUSH) 하기 >> 4 3 2 1 ….. >> PUSH Observable<String> observable = Observable.create( new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("Hello, world!"); // 데이터 PUSH … next subscriber.onCompleted(); // 데이터 PUSH 이제 그만(완료) 할게.. } } );
  • 13. 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"); } };
  • 14. 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( ……
  • 15. 15 RxJava Hello, World! // java 7 Observable.just("Hello, world!").subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } }); // java 8 Observable.just("Hello, world!").subscribe(System.out::println); // Outputs // Hello, world!
  • 16. 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 …..
  • 17. 17
  • 18. 18
  • 19. 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 +
  • 20. 20 1 2 3 4 5 6 … recommendService .requestRecommends(id) RxJava +
  • 21. 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 +
  • 22. 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()); }
  • 23. 23 1 2 3 4 5 6 … recommendService .requestRecommends(id) 1 2 3 4 5 unsubscribe .take(5) RxJava +
  • 24. 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 +
  • 25. 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
  • 26. 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 +
  • 27. 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
  • 28. 28 ……………… .flatMap(recommend -> { // async 1 Observable<GoodsMetaInfo> goodsMetaInfo = goodsMetaInfo.findOne(recommend.id()) …….. RxJava +
  • 29. 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
  • 30. 30 ……………… .flatMap(recommend -> { // async 1 Observable<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 +
  • 31. 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
  • 32. 32 RxJava ……………… .flatMap(recommend -> { // async 1 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; }); // async 2 Observable<GoodsRating> goodsRating = goodsRating.findOne(recommend.id()); ……. …. }) ……..
  • 33. 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
  • 34. 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 3 return 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 +
  • 35. 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 +
  • 36. 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 +
  • 37. 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 +
  • 38. 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 +
  • 39. 39
  • 40. 40
  • 41. 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 +
  • 43. 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 +
  • 44. 44 RxJava + request Netty tcpwrite response tcpwrite public Channel… @Override public 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…
  • 45. 45 RxJava + Netty public class ClientRequestHandler extends SimpleChannelInboundHandler<Object> { private final ConcurrentHashMap QUEUE = new ConcurrentHashMap<String, Subscriber<?>>; public ClientRequestHandler(){ }
  • 46. 46 RxJava + Netty public 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")}); }; @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object object) throws Exception { Subscriber subscriber = (Subscriber)this.QUEUE.remove("requestId"); if(subscriber==null) return; subscriber.onNext(object); subscriber.onCompleted(); }
  • 47. 47 RxJava + Netty @Override public 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…
  • 48. 48
  • 49. 49
  • 50. 50
  • 51. 51
  • 52. OOP CACHE RDBMS 1995 2015 HADOOP NOSQL FP, RX, FRP … 지금은 POLYGLOT 시대…
  • 53. 53 http://www.manning.com/blackheath http://www.slideshare.net/InfoQ/functional-reactive-programming-in-the-netflix-api https://youtu.be/-P28LKWTzrI Towards Reactive Programming for Object-oriented Applications.pdf http://www.slideshare.net/misgod/functional-41887638 http://ent.hankyung.com/news/app/newsview.php?aid=2014112839734