前回、サーバーサイドSwiftのSlimaneの記事(SwiftのWebフレームワークSlimaneをインストールする)を書きましたが、Mediumに詳しい記事が載っていたので翻訳してみました。
この記事はServer Side Swift with Slimaneの翻訳になります。
追記
2016年08月26日
Slimane及びSwift3のアップデートに伴い、現在この記事の内容は最新版では動きません。下記のスライドに最新の情報が載っているのでぜひご覧下さい。
2016年08月19日
iOSDC Japan 2016のイベントでSlimaneの発表がありました。
スライドがこちらにあるのでよければご一緒に読んでみてください。
Slimaneとは?
expressにインスパイアされたSwift3で書かれたマイクロフレームワーク兼HTTPサーバーです。
説明をはじめる前に、なぜ書き始めたのか経緯を説明します。
私は、エンジニアとしての多くの時間を、インフラ・バックエンド・データアナリシス・Web開発に費やしました。なので、Swiftに関して十分な経験がありません。(特にiOSとCocoa)
ですが、2015年3月にLifeCLIPS(Mediumのようなブログプラットフォーム)というiOSアプリで初めてSwiftを書く機会を得ました。強い型付けシステムと軽量プログラミング言語(RubyやJavaScript)並みの柔軟さを持つSwiftをすぐに好きになりました。
オープンソースになったSwift
その後、2015年12月にオープンソースになったSwift。
そこで、私はSlimaneを作ろうと思いました。
まずは、週末の趣味としてプロジェクトをはじめ、隙間時間とはいえモダンWebシステムに必要な機能を日々作成していきました。
作っていくうちにあることに気が付きました。これは実際のプロジェクトで使えるのではないかということです。(なのでSwift3の安定板リリースを待ち望んでいます)
特徴
- 100%非同期とイベントループのバックエンド(libuv)
- 自身がHTTP Serverとして機能
- 速い
- モジュール指向
- 非同期のStream, TCP, Pipe, FileSystem, Process, Timerなどをサポート
- Open-Swiftを採用している
利用できるミドルウェアとモジュール
WS: Websoketサーバー/クライアント
Hanger: 非同期HTTPクライアント
Thrush: 軽量なPromise実装
QWFuture: uv_queue_work
を使ったfuture実装
Session: SessionミドルウェアはSlimaneでsessionを有効化
Redis: RedisクライアントとSession用のRedisStore
BodyParser: HTTP RequestのBodyパーサー(JSON,FormDataに対応)
TemplateEngine: MustacheとJavaScriptテンプレート
その他はこちら https://github.com/slimane-swift
導入に関して
ゴールはSwiftでサーバーを建てていつくかのサンプルを実際に動かす事です。
この記事では一切のコードは書かないので、ついてきてください。
インストール
インストールガイドに従って下さい。
https://github.com/noppoMan/Slimane/wiki/Install-Guide
サーバーを立ち上げる
cd /path/to/your/slimane-example
make debug
.build/debug/SlimaneExample
ターミナルでは0.0.0.0:3000
でlistenしたと表示されています。
ブラウザで確認してみましょう。
このように動いていれば成功です!
もっと試そう
sliman-exampleでは、実用的なサンプルをたくさん試すことができます。
チャットアプリとWeb Socket
これはローカルマシンで動いていますが、もしRedisクライアントがPub/Subをサポートすると、パケットをサーバー間でブロードキャストする事ができます。またSlimaneを使ってSocket.ioのバックエンド実装を作ろうと思っています。あったらうれしいですか?
ブロッキングAPIとの共存
現在、私達のプロジェクトではMySQLはまだありません。ただ、心配しないで下さい 私たちは他のSwiftオープンソースソフトウェアであるZewo/Mysqlやnovi/mysql-swiftなどを使うことができます。
ブロッキングAPIの問題
ただし、ひとつ大きな問題があります。
ほとんどのMySQLクライアントはlibmysqlclient
に依存しているため、i/o
のブロックが発生します。
それは、i/oの完了を待っている間にevent loopがブロックされることを意味します。
では、やはりフルスクラッチでノンブロッキング処理を作る必要があるのでしょうか?
違います!!
QWFutureとThrush
QWFutureを使うことでi/o
のブロックを疑似的に避ける事ができます。これはuv_queue_work
をfutureシンタックスで作り直したものです。
またこれらをThrush(Promise)と組み合わせる事でモダンな非同期フローを作ることができます。
QWFuture内のクロージャはuv_queue_work
の内部つまり、プール済みの別スレッドで実行されます。(この時スレッドの終了までブロックしません)
クロージャ内のタスクが完了するかエラーが発生したタイミングでfuture.onSuccess
またはfuture.onFailure
が呼ばれ処理がメインループに戻ります。
マルチプロセス環境におけるクラスターモード
Slimaneでは1スレッドで1つのインスタンスが実行されます。マルチコア環境では、クラスターモードで起動する事でSlimaneプロセスを活用できます。
このコードはマスターとワーカープロセスの初期化をしています。(これはNode.jsのクラスターモジュールに少し似ています)
--cluster
オプションを付けて実行する事でクラスターを使用できます。
順番に異なるワーカーがリクエストを処理しています。
どうでしたか?
SlimaneはSession/CookieやJSON・Rest api サーバーなどWebアプリを構築する多くの機能を持っています。
現状に関して
Slimaneは主要がフレームワークになることはちょっと考えづらいですが、サーバーサイドSwiftがどのように動くのか、またそれはとても楽しいことだということをみなさんに伝える上で重要な役割を担うことができたら本望です
Slimaneは私が一人で作ってきましたが、コミュニティが作られる事を望みます。少しでもSlimaneに興味を持った方は私(yuki@miketokyo.com)に連絡をください。
あとがき
作者のYuki Takeiさんは日本人なのでメールなどは全部、日本語で大丈夫なようです。興味があれば連絡を取ってみてください。