SlideShare a Scribd company logo
サーバーサイドでの非同期処
理で色々やったよ
Koji Lin, LINE Fukuoka
@kojilin
自己紹介
● LINE Fukuoka Corp
○ Java でサーバーサイド開発
● Taiwan Java User Group メンバー
○ https://www.meetup.com/taiwanjug/
全てがシンプルだった
List<Item> getRanking(String country) {
String rankingType = dao.getRankingType("JP");
return dao.getRanking(rankingType).stream()
.map(item -> ...)
.collect(toList());
}
複雑化していくシステム
List<Item> getRanking(String country) {
String rankingType = api.getRankingType("JP");
List<String> rankingIds =
searchClient.getRanking(rankingType);
return rankingIds.stream()
.map(dao::getItem)
.map(...)
.collect(toList());
}
● パフォーマンスや機能の追加/複雑さを軽減するため、いろん
なサービス/ミドルウェア/チームに分ける
Latency が上がっていく
● いろんな API やミドルウェア等のアクセスが増え、各リモート
のラウンドトリップの積み重ね
● リクエストスレッドがブロックされて、軽いリクエストも影響を受
ける
何故サーバーサイドで非同期?
● 並行できるタスクも自然に順序に書いてしまう
● 1 スレッド 1 リクエスト
○ 同時処理数 <= 最高スレッド数
○ 重い処理が軽い処理をブロック
○ CPU とメモリの無駄遣い
■ デフォルトの -Xss は 1024KB
■ コンテキストスイッチのコスト
同期なコードを非同期に書き直す
● フレームワークの変更
● 戻り値の型は Guava ListenableFuture を選択
○ CompletableFuture に対応するライブラリがまだ少ない
○ Futures#transform で非同期が組み合わせれる
○ Dagger で非同期 DI が利用できる
● ストレージアクセス
● リモート API アクセス
フレームワークを社内製品へ
● RESTful と Thrift RPC のエンドポイントを提供
○ Spring Web/Spark と Facebook Nifty を使っていた
● 社内製でオープンソースの Armeria に移行
○ https://github.com/line/armeria
○ Netty ベース HTTP/2 対応の非同期 RPC/REST library
● 実際 Nifty + swift で非同期も可能です
○ https://github.com/facebook/swift
○ その swift ではない !
REST Controller も非同期へ
● 全てのフレームワークを Spring Web
● 一部同期の Controller から非同期
○ Spring Web の DeferredResult<T>
@RequestMapping("/hello")
public DefferredResult<String> hello() {
DeferredResult<String> deferredResult = new
DeferredResult<>();
... // callback で deferredResult.setResult("hello");
return deferredResult;
}
Thrift とは?
● RPC フレームワーク
● .thrift の IDL を定義
service HelloService{
string hello(1: string name)
}
● Thrift Compiler で対応の言語のコードを生成
● ロジックを入れて、サポートしてるライブラリ上でデプロイすれ
ば良い
同期の Iface から非同期の AsyncIface へ
@Override
public String hello(String name) {
return "Hello, " + name + '!';
}
@Override
public void hello(String name,
AsyncMethodCallback<String> resultHandler) {
resultHandler.onComplete("Hello, " + name + '!');
}
ストレージアクセス
● MySQL
○ MyBatis
○ Guava ListeningExecutorService と組み合わせる
■ Async JDBC 自体がまだ無い
● MongoDB
○ MongoDB Asynchronous Java Driver に変更
MyBatis の API
<E> List<E> selectList(String statement,
Object parameter);
JDBC のアクセスを非同期に
ListeningExecutorService executor;
public <E> ListenableFuture<List<E>> selectList(
String statement, Object parameter) {
return executor.submit(() ->
delegate.selectList(statement, parameter));
}
MongoDB のアクセスを非同期に
private MongoCollection<Model> collection;
public void list(String id, int offset, int limit,
SingleResultCallback<Model> callback) {
collection.find(eq(ID, id))
.skip(offset)
.limit(limit).into(list, callback));
}
MongoDB を ListenableFuture に
public ListenableFuture<List<Model>> list(
String id, int offset, int limit) {
SettableFuture<List<Model>> future =
SettableFuture.create();
collection.find(eq(ID, id))
.skip(offset)
.limit(limit).into(list, (result, t) -> {
if (t != null) { future.setException(t); }
else { future.set(result); }
});
return future;
}
リモート API アクセス
● Apache HttpComponents から Armeria の HttpClient へ
○ Apache HttpComponents にも Async Client がある
● REST API が多すぎるので、Retrofit を利用して、ネットワーク
層は Armeria の HttpClient
Retrofit と併用
● Retrofit で API を Java コードへマッピングする
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service =
retrofit.create(GitHubService.class);
Retrofit と GuavaCallAdapterFactory
● Retrofit は戻り値の型を拡張できる
public interface GitHubService {
@GET("users/{user}/repos")
ListenableFuture<List<Repo>> listRepos(
@Path("user") String user);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addCallAdapterFactory(
GuavaCallAdapterFactory.create())
.build();
IO 関連のアクセスを全て非同期化
Guava の transform で組み合わせ
ListenableFuture<String> result =
FuturesExtra.syncTransform(
dao.getUser("id"),
user -> user.getName());
ListenableFuture<Image> result =
Futures.transformAsync(
dao.getUser("id"),
user -> apiClient.getIcon(user));
Concurrent 化
● Zipkin でアクセスチェック
移行で大変だったとこ
● 同期から非同期の慣れ、特にコードがどっちも併存してい
る時、Future#get に逃げやすい
○ 非同期で event-loop、thread-pool を使うので、小さ
なブロックもパフォーマンスに影響が出る
○ リクエストからレスポンスまでの完全な非同期コードを
準備する
○ コードレビューを頑張る
移行で大変だったとこ
● 次の非同期タスクの発火スレッドは?
○ リクエスト関連の情報をフレームワークのイベントループ
ThreadLocal を多用している
○ デフォルトでは今のスレッドか前のタスクのスレッドを使う
○ transform メソッドで executor を設定する
Futures.transformAsync(
dao.getUser("id"),
user -> apiClient.getIcon(user),
executor);
その他
● Spotify の Futures-extra を多用
○ https://github.com/spotify/futures-extra
○ Guava 19 で transform メソッドのオーバロディングで
コンパイルウォーニングがめんどくさい
● AsyncRetrier と ConcurrencyLimiter も便利
AsyncRetrier
int retryCount = 3;
int delayMillis = 100;
AsyncRetrier retrier = AsyncRetrier.create(
Executors.newSingleThreadScheduledExecutor());
ListenableFuture<List<String>> listFuture =
retrier.retry(() -> api.listByRanking("JP"),
retryCount,
delayMillis);
ConcurrencyLimiter
int maxConcurrentCount = 100;
int maxQueueSize = 1000;
ConcurrencyLimiter<List<String>> concurrencyLimiter =
ConcurrencyLimiter.create(maxConcurrentCount,
maxQueueSize);
ListenableFuture<List<String>> listFuture =
concurrencyLimiter.add(() ->
dao.listByRanking("JP"));
● 非同期化で一気にリモートアクセスが一杯流せてリソー
スを喰いつくすのを防ぐ
これが複雑になっていくと!?
Futures.transformAsync(
Futures.transformAsync(getRankingType("JP"),
dao::listByRanking,
executor),
ids -> Futures.allAsList(ids.stream()
.map(client::getUserById)
.collect(toList())),
executor);
これが複雑になっていくと!?
Futures.transformAsync(
Futures.transformAsync(getRankingType("JP"),
dao::listByRanking,
executor),
ids -> Futures.allAsList(ids.stream()
.map(client::getUserById)
.collect(toList())),
executor);
これが複雑になっていくと!?
Futures.transformAsync(
Futures.transformAsync(getRankingType("JP"),
dao::listByRanking,
executor),
ids -> Futures.allAsList(ids.stream()
.map(client::getUserById)
.collect(toList())),
executor);
これが複雑になっていくと!?
Futures.transformAsync(
Futures.transformAsync(getRankingType("JP"),
dao::listByRanking,
executor),
ids -> Futures.allAsList(ids.stream()
.map(client::getUserById)
.collect(toList())),
executor);
Dagger Producers で複雑さを軽減
● Dagger
○ コンパイル時依存性を解決する DI フレームワーク
● Dagger Producers
○ 非同期な DI を実現
○ メソッドのリターンタイプを ListenableFuture<T> にして、
受取メソッドのパラメータを T にすると Dagger がよしなに
組み合わせてくれる
@ProducerModule
public static class RankingGraph {
@ProductionComponent(modules = { RankingGraph.class, ExecutorModule.class })
interface Component {
ListenableFuture<List<Item>> getRanking();
}
public RankingGraph(Service service, String country) {
...
}
@Produces
public ListenableFuture<String> getRankingType() {
return service.getRankingType(country);
}
@Produces
public ListenableFuture<List<String>> listByRanking(String type) {
return service.listByRanking(type);
}
@Produces
public ListenableFuture<List<Item>> listUsers(List<String> ids) {
return Futures.allAsList(ids.stream().map(service::getItemById).collect(toList()));
}
}
@ProducerModule
public static class RankingGraph {
@ProductionComponent(modules = { RankingGraph.class, ExecutorModule.class })
interface Component {
ListenableFuture<List<Item>> getRanking();
}
public RankingGraph(Service service, String country) {
...
}
@Produces
public ListenableFuture<String> getRankingType() {
return service.getRankingType(country);
}
@Produces
public ListenableFuture<List<String>> listByRanking(String type) {
return service.listByRanking(type);
}
@Produces
public ListenableFuture<List<Item>> listUsers(List<String> ids) {
return Futures.allAsList(ids.stream().map(service::getItemById).collect(toList()));
}
}
@ProducerModule
public static class RankingGraph {
@ProductionComponent(modules = { RankingGraph.class, ExecutorModule.class })
interface Component {
ListenableFuture<List<Item>> getRanking();
}
public RankingGraph(Service service, String country) {
...
}
@Produces
public ListenableFuture<String> getRankingType() {
return service.getRankingType(country);
}
@Produces
public ListenableFuture<List<String>> listByRanking(String type) {
return service.listByRanking(type);
}
@Produces
public ListenableFuture<List<Item>> listUsers(List<String> ids) {
return Futures.allAsList(ids.stream().map(service::getItemById).collect(toList()));
}
}
@ProducerModule
public static class RankingGraph {
@ProductionComponent(modules = { RankingGraph.class, ExecutorModule.class })
interface Component {
ListenableFuture<List<Item>> getRanking();
}
public RankingGraph(Service service, String country) {
...
}
@Produces
public ListenableFuture<String> getRankingType() {
return service.getRankingType(country);
}
@Produces
public ListenableFuture<List<String>> listByRanking(String type) {
return service.listByRanking(type);
}
@Produces
public ListenableFuture<List<Item>> listUsers(List<String> ids) {
return Futures.allAsList(ids.stream().map(service::getItemById).collect(toList()));
}
}
Dagger が生成したコード
呼び出しコード
ListenableFuture<List<Item>> result =
DaggerRankingGraph_Component
.builder()
.rankingGraph(new RankingGraph(service, "JP"))
.build()
.getRanking();
Dagger を使ったメリット
● transformAsync 等でのネストが減った
● 発火スレッドが全て ExecutorModule で指定した executor で
始まる
● Convention 化し易い
● メソッド毎にバラバラで書いても、コンパイルタイムで揃ってる
か検査してくれる
● 実際 Guava ドキュメントも勧めてる(?)
これで一通り完成
Thread 数の減少
Latency の改善
Latency の改善
CPU 利用率の改善
CompletableFutureが増えてきた
● CompletableFuture は Java 8 で追加されてるので、
ライブラリ開発者は優先に使い始める
● けどコードベースはほとんど Guava ListenableFuture
● Dagger もがんがん使っている
● Spotify の Future-extra の CompletableFutureExtra で
ListenableFuture に変換
なぜ RxJava2 に移行した?
● ListenableFuture だけで組み合わせが書きやすくない
○ Guava 23 で FluentFuture がある
● Dagger Producers
○ Module の再利用が大変だった
○ 微妙に読みやすくない
● RxJava2 がそろそろ安定してそうだった
RxJava2
● Java VM implementation of Reactive Extensions
● A library for composing asynchronous and event-based
programs by using observable sequences.
RxJava2
● Single<T>
○ 1 個のデータ
○ CompletableFuture<T> で中身は絶対 null ではない
● Maybe<T>
○ 空っぽか1個のデータ
○ CompletableFuture<T> で中身は null かも知れない
● Completable
○ 空っぽ
○ CompletableFuture<Void>
RxJava2
● Observable<T>
○ 0 から n 個のデータ
○ backpressure なし
○ 基本サーバサイドでは使わない
● Flowable<T>
○ 0 から n 個のデータ
○ backpressure あり
RxJava2 でサーバサイド
● サーバでリモートアクセスは基本 1 リクエスト/1レスポンスな
ので、Single<T>、Maybe<T> と Completable で API を設計
できる
RxJava2 で設計した API
class UserDao {
public Single<User> get(String id){...}
public Maybe<User> find(String id){...}
public Completable delete(String id){...}
public Flowable<User> listAll(){...}
public Single<List<User>> listAllSingle(){...}
}
JDBC のアクセスを RxJava2 に
ListeningExecutorService asyncExecutor;
public <E> Single<List<E>> selectListRx(
String statement, Object parameter) {
return toSingle(asyncExecutor.submit(() ->
delegate.selectList(statement, parameter)));
}
MongoDB を RxJava2 に
Public Single<List<Model>> listRx(
String id, int offset, int limit) {
SettableFuture<List<Model>> future =
SettableFuture.create();
collection.find(eq(ID, id))
.skip(offset)
.limit(limit).into(list, (result, t) -> {
if (t != null) { future.setException(t); }
else { future.set(result); }
});
return toSingle(future);
}
MongoDB を RxJava2 に
● 実際 MongoDB には reactive extension 対応の Driver があ
るので、それを RxJava2 化すればいい
Public Single<List<Model>> listRx(
String id, int offset, int limit) {
return Flowable.fromPublisher(
collection.find(eq(ID, id))
.skip(offset)
.limit(limit))
.toList();
}
Retrofit と RxJava2CallAdapterFactory
● Retrofit の戻り値の型をRxJava2 に
public interface GitHubService {
@GET("users/{user}/repos")
Single<List<Repo>> listRepos(
@Path("user") String user);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addCallAdapterFactory(
RxJava2CallAdapterFactory.create())
.build();
非同期の組み合わせ
Single<List<User>> ranking =
api.getRankingType("JP")
// Single<List<String>>
.flatMapSingle(this::listByRanking)
// Flowable<String>
.flatterAsFlowable(list -> list)
.concatMapEager(this::getUserById)
.toList();
@ProducerModule
public static class RankingGraph {
@ProductionComponent(modules = { RankingGraph.class, ExecutorModule.class })
interface Component {
ListenableFuture<List<Item>> getRanking();
}
public RankingGraph(Service service, String country) {
...
}
@Produces
public ListenableFuture<String> getRankingType() {
return service.getRankingType(country);
}
@Produces
public ListenableFuture<List<String>> listByRanking(String type) {
return service.listByRanking(type);
}
@Produces
public ListenableFuture<List<Item>> listUsers(List<String> ids) {
return
Futures.allAsList(ids.stream().map(service::getItemById).collect(toList()));
}
}
ListenableFuture<List<Item>> result =
DaggerRankingGraph_Component
.builder()
.rankingGraph(new RankingGraph(service, "JP"))
.build()
.getRanking();
リトライ
api.listByRanking("JP")
.retry(10)
.flatMap({
...
})... //
リトライ
api.listByRanking("JP")
.retryWhen(throwableFlowable -> {
return throwableFlowable.flatMap(thrown -> {
if (thrown instanceof IOException) {
return Flowable.timer(1000,
MILLISECONDS);
}
return Flowable.error(thrown);
}).flatMap({
...
})... //
移行で大変だったとこ
● ListenableFuture と Dagger で慣れ始めたのに、またかよ...
○ RxJava2 は Stream API な感じでつなげていけるので、で
きれば同じような感覚で開発してもらいたい
○ Project Reactor とかもあるし、似てるようなプログラミング
手法がでてくる
移行で大変だったとこ
● RxJava は null を容赦しない !
○ Flowable/Single/Maybe に null を入れたら、NPE !
Single.just("koji")
.map(id -> null) // NPE !!!
...//
移行で大変だったとこ
● Eager vs Lazy
○ Future<User> getUser(String id)
■ 呼んだ瞬間に発火
○ Single<User> getUser(String id)
■ 戻り値に subscribe した時に発火
■ でも RxJava2 と Future 変換があるので、実はそうで
もない
移行で大変だったとこ
● subscribe は絶対 Spring web controller と thrift handler で
呼ぶ
○ 他の層での subscribeOn は基本出現しない方向
移行で大変だったとこ
● Flowable の flatMap vs concatEagerMap
○ 順番守りたいなら concatEagerMap
http://www.nurkiewicz.com/2017/08/flatmap-vs-concatmap-vs-co
ncatmapeager.html
Flowable.just("koji", "kishida", "tempo")
.flatMapSingle(id -> api.fetchUser(id))
...//
Flowable.just("koji", "kishida", "tempo")
.concatMapEager(id ->
api.fetchUser(id).toFlowable())
...//
移行で大変だったとこ
● 複数回 subscribe 問題
Single<User> user = client.getUser("1234");
Single<Profile> first = user.map(...)...;
Single<Company> second = user.map(...)...;
Single.zip(first, second, (profile, address) -> {
...
})...;
移行で大変だったとこ
● 複数回 subscribe 問題
Single<User> user = client.getUser("1234").cache();
Single<Profile> first = user.map(...)...;
Single<Company> second = user.map(...)...;
Single.zip(first, second, (profile, address) -> {
...
})...;
移行で大変だったとこ
● 同じく発火スレッド問題
api.getRankingType("JP")
.flatMap(type -> getRanking(type)) // どの thread?
.flatMap(ids -> xxx) // どの thread?
.map(...)
.... // 色々
移行で大変だったとこ
● 次に非同期がある前に必ず observeOn
api.getRankingType("1234")
.ovserveOn(Schedulers.from(executor))
.flatMap(type -> getRanking(type))
.ovserveOn(Schedulers.from(executor))
.flatMap(ids -> xxx)
.map(...) // map 且つ重くないならいらない
.ovserveOn(Schedulers.from(executor))
  .flatMap(...)
.... // 色々
その他
● RxJava2 と Java8 CompletableFuture の変換ライブラ
リ
○ akarnokd/RxJava2Jdk8Interop
● Debugging と色々な便利 operators/transformers
○ akarnokd/RxJava2Extensions
例えば filterAsync
Flowable.just(...)
.compose(FlowableTransformers.filterAsync(
user -> {
return dao.isAvailable(user);
}))
.map(...)
...
これから...
● Java には extension method みたいなものがないので、
filterAsync みたいな compose でするしかない
● 複雑な組み合わせ以外は、async/await みたいなものがほし
い
● ……..kotlin かな?
資料とか
● Reactive Programming with RxJava
● Going Reactive with Spring 5 & Project Reactor
○ Devoxx youtube: https://youtu.be/yAXgkSlrmBA
Q&A

More Related Content

What's hot

より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
NTT DATA Technology & Innovation
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
Masahiro Sakai
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
Takuto Wada
 
JavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だったJavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だった
iPride Co., Ltd.
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
 
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
Preferred Networks
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
Yahoo!デベロッパーネットワーク
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Takuto Wada
 
型安全性入門
型安全性入門型安全性入門
型安全性入門
Akinori Abe
 
Rustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったかRustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったか
ShunsukeNakamura17
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
mosa siru
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
Kumazaki Hiroki
 
Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化
Yusuke Fujimoto
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろうKota Mizushima
 
Prometheus at Preferred Networks
Prometheus at Preferred NetworksPrometheus at Preferred Networks
Prometheus at Preferred Networks
Preferred Networks
 
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
Sadayuki Furuhashi
 
Unified JVM Logging
Unified JVM LoggingUnified JVM Logging
Unified JVM Logging
Yuji Kubota
 
REST API のコツ
REST API のコツREST API のコツ
REST API のコツ
pospome
 
TLS, HTTP/2演習
TLS, HTTP/2演習TLS, HTTP/2演習
TLS, HTTP/2演習
shigeki_ohtsu
 
ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方
Yoshiyasu SAEKI
 

What's hot (20)

より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
JavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だったJavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だった
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
ゼロから作るKubernetesによるJupyter as a Service ー Kubernetes Meetup Tokyo #43
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
型安全性入門
型安全性入門型安全性入門
型安全性入門
 
Rustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったかRustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったか
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化Tensor コアを使った PyTorch の高速化
Tensor コアを使った PyTorch の高速化
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
Prometheus at Preferred Networks
Prometheus at Preferred NetworksPrometheus at Preferred Networks
Prometheus at Preferred Networks
 
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
 
Unified JVM Logging
Unified JVM LoggingUnified JVM Logging
Unified JVM Logging
 
REST API のコツ
REST API のコツREST API のコツ
REST API のコツ
 
TLS, HTTP/2演習
TLS, HTTP/2演習TLS, HTTP/2演習
TLS, HTTP/2演習
 
ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方
 

Similar to サーバーサイドでの非同期処理で色々やったよ

ゆるふわJava8入門
ゆるふわJava8入門ゆるふわJava8入門
ゆるふわJava8入門
dcubeio
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-Kazunari Hara
 
Implementation patterns
Implementation patternsImplementation patterns
Implementation patterns
Tatsuya Maki
 
初めての Data api
初めての Data api初めての Data api
初めての Data api
Yuji Takayama
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
Fujio Kojima
 
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTC getStats - WebRTC Meetup Tokyo 5 LTWebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
mganeko
 
Data api workshop at Co-Edo
Data api workshop at Co-EdoData api workshop at Co-Edo
Data api workshop at Co-EdoYuji Takayama
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック
庸介 高橋
 
初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣
Yuji Takayama
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライ
Masanobu Sato
 
Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界
Yuji Takayama
 
Entity Framework
Entity FrameworkEntity Framework
Entity Framework
Nakashima Yujiro
 
初めての Data API CMS どうでしょう - 仙台編 -
初めての Data API   CMS どうでしょう - 仙台編 -初めての Data API   CMS どうでしょう - 仙台編 -
初めての Data API CMS どうでしょう - 仙台編 -
Yuji Takayama
 
Rubyとクラウドサービスで実現したEC決済共通基盤@Ruby Association ビジネスセミナー201401
Rubyとクラウドサービスで実現したEC決済共通基盤@Ruby Association ビジネスセミナー201401Rubyとクラウドサービスで実現したEC決済共通基盤@Ruby Association ビジネスセミナー201401
Rubyとクラウドサービスで実現したEC決済共通基盤@Ruby Association ビジネスセミナー201401
Shota Onishi
 
Dynamic Data
Dynamic DataDynamic Data
Rx java x retrofit
Rx java x retrofitRx java x retrofit
Rx java x retrofit
Shun Nakahara
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter IntegrationKazuki Nakajima
 

Similar to サーバーサイドでの非同期処理で色々やったよ (20)

ゆるふわJava8入門
ゆるふわJava8入門ゆるふわJava8入門
ゆるふわJava8入門
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
Implementation patterns
Implementation patternsImplementation patterns
Implementation patterns
 
初めての Data api
初めての Data api初めての Data api
初めての Data api
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTC getStats - WebRTC Meetup Tokyo 5 LTWebRTC getStats - WebRTC Meetup Tokyo 5 LT
WebRTC getStats - WebRTC Meetup Tokyo 5 LT
 
Data api workshop at Co-Edo
Data api workshop at Co-EdoData api workshop at Co-Edo
Data api workshop at Co-Edo
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック
 
初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライ
 
Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界Data apiで実現 進化するwebの世界
Data apiで実現 進化するwebの世界
 
Entity Framework
Entity FrameworkEntity Framework
Entity Framework
 
初めての Data API CMS どうでしょう - 仙台編 -
初めての Data API   CMS どうでしょう - 仙台編 -初めての Data API   CMS どうでしょう - 仙台編 -
初めての Data API CMS どうでしょう - 仙台編 -
 
Rubyとクラウドサービスで実現したEC決済共通基盤@Ruby Association ビジネスセミナー201401
Rubyとクラウドサービスで実現したEC決済共通基盤@Ruby Association ビジネスセミナー201401Rubyとクラウドサービスで実現したEC決済共通基盤@Ruby Association ビジネスセミナー201401
Rubyとクラウドサービスで実現したEC決済共通基盤@Ruby Association ビジネスセミナー201401
 
Dynamic Data
Dynamic DataDynamic Data
Dynamic Data
 
Cubby 2008-09-06
Cubby 2008-09-06Cubby 2008-09-06
Cubby 2008-09-06
 
Rx java x retrofit
Rx java x retrofitRx java x retrofit
Rx java x retrofit
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 

More from koji lin

G1GC
G1GCG1GC
G1GC
koji lin
 
Using armeria to write your RPC
Using armeria to write your RPCUsing armeria to write your RPC
Using armeria to write your RPC
koji lin
 
使用 Java 上的 future/promise API
使用 Java 上的 future/promise  API使用 Java 上的 future/promise  API
使用 Java 上的 future/promise API
koji lin
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
koji lin
 
Jcconf
JcconfJcconf
Jcconf
koji lin
 
Use Lambdas in Android
Use Lambdas in AndroidUse Lambdas in Android
Use Lambdas in Android
koji lin
 
docker intro
docker introdocker intro
docker introkoji lin
 
Java8 time
Java8 timeJava8 time
Java8 timekoji lin
 
Java8 stream
Java8 streamJava8 stream
Java8 streamkoji lin
 
Java8 lambda
Java8 lambdaJava8 lambda
Java8 lambdakoji lin
 
CompletableFuture
CompletableFutureCompletableFuture
CompletableFuturekoji lin
 
Raspberry Pi with Java
Raspberry Pi with JavaRaspberry Pi with Java
Raspberry Pi with Javakoji lin
 
Services you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appServices you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appkoji lin
 
Programming with Threads in Java
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Javakoji lin
 
JQuery
JQueryJQuery
JQuery
koji lin
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發
koji lin
 
Android Location-based應用開發分享
Android Location-based應用開發分享Android Location-based應用開發分享
Android Location-based應用開發分享
koji lin
 

More from koji lin (18)

G1GC
G1GCG1GC
G1GC
 
Using armeria to write your RPC
Using armeria to write your RPCUsing armeria to write your RPC
Using armeria to write your RPC
 
使用 Java 上的 future/promise API
使用 Java 上的 future/promise  API使用 Java 上的 future/promise  API
使用 Java 上的 future/promise API
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
Jcconf
JcconfJcconf
Jcconf
 
Use Lambdas in Android
Use Lambdas in AndroidUse Lambdas in Android
Use Lambdas in Android
 
docker intro
docker introdocker intro
docker intro
 
Java8 time
Java8 timeJava8 time
Java8 time
 
Java8 stream
Java8 streamJava8 stream
Java8 stream
 
Java8 lambda
Java8 lambdaJava8 lambda
Java8 lambda
 
Idea13
Idea13Idea13
Idea13
 
CompletableFuture
CompletableFutureCompletableFuture
CompletableFuture
 
Raspberry Pi with Java
Raspberry Pi with JavaRaspberry Pi with Java
Raspberry Pi with Java
 
Services you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile appServices you can use to monitor and analyze mobile app
Services you can use to monitor and analyze mobile app
 
Programming with Threads in Java
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Java
 
JQuery
JQueryJQuery
JQuery
 
山頂洞人日記 - 回歸到最純樸的開發
山頂洞人日記 -  回歸到最純樸的開發山頂洞人日記 -  回歸到最純樸的開發
山頂洞人日記 - 回歸到最純樸的開發
 
Android Location-based應用開發分享
Android Location-based應用開發分享Android Location-based應用開發分享
Android Location-based應用開發分享
 

Recently uploaded

単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
Fukuoka Institute of Technology
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
atsushi061452
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
Matsushita Laboratory
 
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
harmonylab
 
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance
 
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
yassun7010
 
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
atsushi061452
 
【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow
Sony - Neural Network Libraries
 
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
NTT DATA Technology & Innovation
 
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
iPride Co., Ltd.
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance
 

Recently uploaded (15)

単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
単腕マニピュレータによる 複数物体の同時組み立ての 基礎的考察 / Basic Approach to Robotic Assembly of Multi...
 
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
論文紹介: Offline Q-Learning on diverse Multi-Task data both scales and generalizes
 
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdfFIDO Alliance Osaka Seminar: Welcome Slides.pdf
FIDO Alliance Osaka Seminar: Welcome Slides.pdf
 
FIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdfFIDO Alliance Osaka Seminar: CloudGate.pdf
FIDO Alliance Osaka Seminar: CloudGate.pdf
 
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdfFIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
FIDO Alliance Osaka Seminar: NEC & Yubico Panel.pdf
 
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
TaketoFujikawa_物語のコンセプトに基づく情報アクセス手法の基礎検討_JSAI2024
 
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
【DLゼミ】XFeat: Accelerated Features for Lightweight Image Matching
 
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdfFIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
FIDO Alliance Osaka Seminar: PlayStation Passkey Deployment Case Study.pdf
 
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
2024年度_サイバーエージェント_新卒研修「データベースの歴史」.pptx
 
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
論文紹介: Exploiting semantic segmentation to boost reinforcement learning in vid...
 
【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow【AI論文解説】Consistency ModelとRectified Flow
【AI論文解説】Consistency ModelとRectified Flow
 
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
YugabyteDB適用に向けた取り組みと隠れた魅力 (DSS Asia 2024 発表資料)
 
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その2) 2024/05/24の勉強会で発表されたものです。
 
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdfFIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
FIDO Alliance Osaka Seminar: LY-DOCOMO-KDDI-Mercari Panel.pdf
 

サーバーサイドでの非同期処理で色々やったよ