FreyaはF#のウェブフレームワークであり、HTTPのプリミティブと並列性に特化している。テンプレート処理のようなインターフェースの構築機能は持っていない。F# eXchange 2017でMarcus Griep氏がFreyaを紹介した。氏はこのフレームワークの中核となるモデルについて説明した。また、性能と並列性で活用できる仕組みを紹介した。HopacとKestrelとの統合についてだ。
Freyaは異なるホストティング環境を構成する。自己ホストアプリケーションとしても動作する。dotnet run
で起動するということだ。Kestrel上でも動く、.NET Frameworkと.NET Coreの両方をサポートする。
性能については、氏はKestrelの上で動かすことを推奨している。Kestrelの多くの最適化の仕組みの恩恵を受けるためだ。氏が示したベンチマークのよれば、"Hello World"がASP.NET Coreで6ミリ秒、Hopac上のFreyaで13ミリ秒、F# Async上のFreyaで26秒だった。
Griep氏のベンチマークが示している通り、HopacはF# Asyncと比べ大幅に性能が改善されている。Hopacはスレッドにプリエンプションではなく、協調モデルを使っている。協調スケジューリングによって、コンテキスト切り替えの発生が少なくなり、CPUをより効率的に利用できる。しかし、長期間実行されるジョブだとこのやり方はうまくいかない。完了まで走り続けるので、実行を待っている他のジョブが動かなくなる可能性がある。
FreyaのプログラミングモデルはHTTPのタイプセーフな抽象を提供しようとしている。計算式freya
はOWINの状態の抽象だ。下のコードはクエリ文字列を取得する例だ。
let name_ = Route.atom_ "name"
let name =
freya {
// Get the query string parameter "name"
let! name = Freya.Optic.get name_
match name with
| Some name -> return name
| None -> return "World" }
let sayHello =
freya {
let! name = name
return Represent.text (sprintf "Hello, %s!" name) }
Freyaの仕組みは決定木の抽象だ。決定はHTTPのルールの一部を表現している。例えば、"CORSヘッダがあるか"というようなルールだ。木の全体は数百の決定を含み、拡張もできる。自動的な最適化や設定とは無関係の決定を除外することも可能だ。
Freyaの仕組みは計算式でも定義できる。次の例は、Hello Worldを返す条件を設定している。
let helloMachine =
freyaMachine {
methods [GET; HEAD; OPTIONS]
handleOk sayHello }
そして、これをルーティングとバインドする。
let router =
freyaRouter {
resource "/hello{/name}" machine }
StackEditで記述した。
Rate this Article
- Editor Review
- Chief Editor Action