|
15 | 15 | - `Subscriber.onComplete()` or `Subscriber.onError(throwable)` is called depending on the situation.
|
16 | 16 | - Reactive Streams implementations in Armeria
|
17 | 17 | - `Publisher` (`StreamMessage`)
|
18 |
| - - `HttpRequest` and `HttpResponse` implement it |
| 18 | + - `HttpRequest` and `HttpResponse` extends it |
19 | 19 | - `DefaultStreamMessage`
|
20 | 20 | - Queue based
|
21 | 21 | - `AbstractStreamMessageDuplicator`
|
|
27 | 27 | - `FilteredStreamMessage`
|
28 | 28 | - What if we want to add some header in the decorator?
|
29 | 29 | - `DeferredStreamMessage`
|
30 |
| - - Let's implement my own subscriber. |
| 30 | + - Deferred? |
| 31 | + - Let's implement our own subscriber. |
31 | 32 | - `Subscriber`
|
32 | 33 | - `HttpMessageAggregator`
|
33 |
| - - `HttpClient.execute(...)` returns an `HttpResponse` which is one of `StreamMessage`s |
| 34 | + - `HttpClient.execute(...)` returns an `HttpResponse`. |
34 | 35 | - You can aggregate the `HttpResponse` using `HttpResponse.aggregate()`.
|
35 |
| - - Then, it will return a `CompletableFuture<AggregatedHttpMessage>`. |
| 36 | + - Then, it will return a `CompletableFuture<AggregatedHttpResponse>`. |
36 | 37 | - In `HttpResponse.aggregate()`, `HttpMessageAggregator` which is a `Subscriber`, subscribes
|
37 | 38 | the `StreamMessage` and it collects all the response.
|
38 | 39 | - `HttpRequestSubscriber`
|
|
45 | 46 | it consumes all the elements.
|
46 | 47 | - `Http1ResponseDecoder` implements `ChannelInboundHandler`.
|
47 | 48 | - `HttpResponseSubscriber` is used by the server side.
|
48 |
| - |
| 49 | + - Let's build a simple decorating service. |
| 50 | + - The difference between `HttpRequest` and `HttpResponse` |
| 51 | + |
49 | 52 | ### Event Loop
|
50 | 53 |
|
51 | 54 | - Who does the all jobs above?
|
52 |
| -- What is Event loop? |
| 55 | +- What is the event loop? |
53 | 56 | - A general term which waits for and dispatches events or messages in a program.
|
54 | 57 | - We use `EventLoop` in Netty.
|
55 | 58 | - Handles all the I/O operations for a `Channel` once registered.
|
56 | 59 | - One `EventLoop` instance usually handles more than one `Channel` but this may depend on implementation details and internals.
|
57 | 60 | - `EventLoop` extends Java's `ScheduledExecutorService`.
|
58 | 61 | - Events and Tasks are executed in order received.
|
59 | 62 | - Let's see what it really does with [`EpollEventLoop`](https://github.com/netty/netty/blob/05e5ab1ecb98963604d686c1f59b2196cf73e244/transport-native-epoll/src/main/java/io/netty/channel/epoll/EpollEventLoop.java#L257)
|
| 63 | + - From the point of view of the `EventLoop`s |
60 | 64 | - How many `EventLoop`s ?
|
61 | 65 | - No official formula
|
62 | 66 | - Nthreads = Ncpu * Ucpu * (1 + W/C)
|
| 67 | +- Let's build a simple reactive server. |
| 68 | + |
| 69 | +### Request flow |
| 70 | + |
63 | 71 | - Sending an `HttpRequest`
|
64 | 72 | - `HttpClient` -> `UserClient` -> HTTP decorators -> `HttpClientDelegate` -> `HttpSessionHandler`
|
65 | 73 | - Creates a `ClientRequestContext` in `UserClient`
|
|
71 | 79 | - So the thread who calls `HttpClient.execute()` and write to the `Channel` can be different.
|
72 | 80 | - Receiving an `HttpResponse`
|
73 | 81 | - The thread who writes to the response is the `EventLoop` you used when sending the `Request`.
|
| 82 | +- Thrift client |
| 83 | + - `HelloSerivce.Iface()` or `AsyncIface()` -> `THttpClientInvocationHandler` -> `DefaultTHttpClient(UserClient)` -> |
| 84 | + RPC decorators -> `THttpClientDelegate` -> HTTP decorators -> `HttpClientDelegate` |
| 85 | + |
| 86 | +### `RequestContext` |
| 87 | + |
| 88 | +- Thread-local storage |
| 89 | + - `makeContextAware` |
74 | 90 |
|
75 | 91 | ### Connection pooling
|
76 | 92 |
|
| 93 | +- How many connections we have? |
| 94 | + - HTTP/1.1 |
| 95 | + - What's the [pipelining](https://en.wikipedia.org/wiki/HTTP_pipelining)? |
| 96 | + - [In Armeria](https://github.com/line/armeria/blob/armeria-0.88.0/core/src/main/java/com/linecorp/armeria/client/HttpClientDelegate.java#L224) |
| 97 | + - HTTP/2 |
| 98 | + - Why is it possible just to have one connection? |
| 99 | + - What Content-length header is for? |
| 100 | + - [Frame format](https://tools.ietf.org/html/rfc7540#section-4.1) |
| 101 | + |
77 | 102 | - Creates a [`PoolKey`](https://github.com/line/armeria/blob/d90aea4704982df06251c1132bbc4da33301725d/core/src/main/java/com/linecorp/armeria/client/HttpClientDelegate.java#L104) with host, ip, port and session protocol.
|
78 | 103 | - Gets a [`KeyedChannelPool`](https://github.com/line/armeria/blob/d90aea4704982df06251c1132bbc4da33301725d/core/src/main/java/com/linecorp/armeria/client/HttpClientFactory.java#L289) using the `EventLoop`.
|
79 |
| -- Gets a healthy `Channel` from the pool using the key. |
80 |
| - |
81 |
| -### Thrift client |
82 | 104 |
|
83 |
| -- `HelloSerivce.Iface()` or `AsyncIface()` -> `THttpClientInvocationHandler` -> `DefaultTHttpClient(UserClient)` -> RPC decorators -> `THttpClientDelegate` -> HTTP decorators -> `HttpClientDelegate` |
| 105 | +### Let's build a proxy server |
0 commit comments