Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

LT「mini Bandit」を作ってみる

presentation.livemd

LT「mini Bandit」を作ってみる

Mix.install([
  {:thousand_island, "~> 1.0"}
])

LTのゴール

  • ちょっとBanditのコードが追えるようになる
  • 小さいHTTPサーバーを動かす

Q. なぜBanditのコード読んでんの?

A. 本当はPhoenixをまるごと高速化したい!

が、いきなりまるごとできないので、機能を少しずつ切り出して高速化するため。

Banditってなに

https://github.com/mtrudel/bandit

TCP/TLS層はThousandIslandに任せて、HTTP1/HTTP2/WebSocket対応したシンプルなサーバー。

graph LR;
  subgraph ThousandIsland
    TCP-->TLS;
  end
  TLS-->HTTP1;
  
  subgraph Bandit
    HTTP1
    HTTP2
    WebSocket
  end
  
  TLS-->HTTP2;
  TLS-->WebSocket;

今日の範囲

graph LR;
  subgraph Today
    HTTP1-->共通処理
  end
  HTTP2-->特有のいろいろ-->共通処理;

共通処理

  • レスポンスの作成
    • ファイル読み込み
    • HTTP1レスポンス
    • (HTTP2やりたかったけど動かんかった)

Bandit Code Reading

https://github.com/mtrudel/bandit

  1. bandit.ex
  2. ThousandIslandのHEx Docsを紹介
  3. https://hexdocs.pm/thousand_island/ThousandIsland.Handler.html
  4. Bandit.InitialHandler
  5. Bandit.HTTP1.Handler

mini Bandit

defmodule HTTPHelloWorld do
  @moduledoc """
  A sample Handler implementation of a simple HTTP Server. Intended to be the
  simplest thing that can answer a browser request and nothing more. Not even
  remotely strictly HTTP compliant.
  """

  use ThousandIsland.Handler

  @impl ThousandIsland.Handler
  def handle_data(_data, socket, state) do
    str = File.read!("./hello_world.html")
    ThousandIsland.Socket.send(socket, "HTTP/1.0 200 OK\r\n\r\n#{str}")
    {:close, state}
  end
end
name = :my_thousand_server
pid = Process.whereis(name)
unless is_nil(pid), do: Supervisor.stop(pid)
{:ok, new_pid} = ThousandIsland.start_link(port: 1234, handler_module: HTTPHelloWorld)
Process.register(new_pid, name)

http://localhost:1234/

もうちょっとBanditっぽくした版

https://github.com/hisaway/codex_fragments/tree/main/mini_bandit