サーバーサイドSwiftとSlimane

前回、サーバーサイドSwiftのSlimaneの記事([SwiftのWebフレームワークSlimaneをインストールする](http://qiita.com/tk1024/items/15f6f0b6af632b9328b4))を書きましたが、Mediumに詳しい記事が載っていたので翻訳してみました。

この記事は[Server Side Swift with Slimane](https://medium.com/@yukitakei/server-side-swift-with-slimane-76238c9471d5)の翻訳になります。

## 追記
### 2016年08月26日
Slimane及びSwift3のアップデートに伴い、現在この記事の内容は最新版では動きません。下記のスライドに最新の情報が載っているのでぜひご覧下さい。

### 2016年08月19日

iOSDC Japan 2016のイベントでSlimaneの発表がありました。
スライドが[こちら](https://speakerdeck.com/noppoman/swift3-framework-slimane-and-server-side-swift-ja)にあるのでよければご一緒に読んでみてください。

# 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](https://github.com/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

### サーバーを立ち上げる
```bash
cd /path/to/your/slimane-example
make debug
.build/debug/SlimaneExample
```

![1*ISCdTovumqqAuz0iNDj8vg.png](https://qiita-image-store.s3.amazonaws.com/0/74405/77e2c7a7-f100-c3f3-b7c9-e4cca0c42a4d.png)

ターミナルでは`0.0.0.0:3000`でlistenしたと表示されています。
ブラウザで確認してみましょう。

![1*uilYwEJJGYxQm7Thg1BTXw.png](https://qiita-image-store.s3.amazonaws.com/0/74405/6c953797-8144-f44c-ef52-b7b95c494448.png)

このように動いていれば成功です！

# もっと試そう
sliman-exampleでは、実用的なサンプルをたくさん試すことができます。

### チャットアプリとWeb Socket
![https://cdn-images-1.medium.com/max/800/1*mlvR-iuux2Url96uaDDL_Q.gif](https://cdn-images-1.medium.com/max/800/1*mlvR-iuux2Url96uaDDL_Q.gif)

これはローカルマシンで動いていますが、もしRedisクライアントがPub/Subをサポートすると、パケットをサーバー間でブロードキャストする事ができます。またSlimaneを使ってSocket.ioのバックエンド実装を作ろうと思っています。あったらうれしいですか？

### ブロッキングAPIとの共存
現在、私達のプロジェクトではMySQLはまだありません。ただ、心配しないで下さい 私たちは他のSwiftオープンソースソフトウェアである[Zewo/Mysql](https://github.com/Zewo/MySQL)や[novi/mysql-swift](https://github.com/novi/mysql-swift)などを使うことができます。

#### ブロッキングAPIの問題
ただし、ひとつ大きな問題があります。
ほとんどのMySQLクライアントは`libmysqlclient`に依存しているため、`i/o`のブロックが発生します。
それは、i/oの完了を待っている間にevent loopがブロックされることを意味します。
では、やはりフルスクラッチでノンブロッキング処理を作る必要があるのでしょうか？

違います!!

### QWFutureとThrush
QWFutureを使うことで`i/o`のブロックを疑似的に避ける事ができます。これは`uv_queue_work`をfutureシンタックスで作り直したものです。
またこれらをThrush(Promise)と組み合わせる事でモダンな非同期フローを作ることができます。
![https://cdn-images-1.medium.com/max/800/1*TEpixug-4Ka-og93QbS-sQ.png](https://cdn-images-1.medium.com/max/800/1*TEpixug-4Ka-og93QbS-sQ.png)

QWFuture内のクロージャは`uv_queue_work`の内部つまり、プール済みの別スレッドで実行されます。(この時スレッドの終了までブロックしません)
クロージャ内のタスクが完了するかエラーが発生したタイミングで`future.onSuccess`または`future.onFailure`が呼ばれ処理がメインループに戻ります。

### マルチプロセス環境におけるクラスターモード
Slimaneでは1スレッドで1つのインスタンスが実行されます。マルチコア環境では、クラスターモードで起動する事でSlimaneプロセスを活用できます。

![https://cdn-images-1.medium.com/max/800/1*z_zUE_MN7jugCLVrsl7Y3A.png](https://cdn-images-1.medium.com/max/800/1*z_zUE_MN7jugCLVrsl7Y3A.png)
このコードはマスターとワーカープロセスの初期化をしています。(これはNode.jsのクラスターモジュールに少し似ています)

![https://cdn-images-1.medium.com/max/800/1*rpqIoxSaeytljtU72-ytSg.png](https://cdn-images-1.medium.com/max/800/1*rpqIoxSaeytljtU72-ytSg.png)
`--cluster`オプションを付けて実行する事でクラスターを使用できます。
![https://cdn-images-1.medium.com/max/800/1*s6egReqzHHspM9v_i8xrrg.png](https://cdn-images-1.medium.com/max/800/1*s6egReqzHHspM9v_i8xrrg.png)
順番に異なるワーカーがリクエストを処理しています。

どうでしたか？
SlimaneはSession/CookieやJSON・Rest api サーバーなどWebアプリを構築する多くの機能を持っています。

# 現状に関して
Slimaneは主要がフレームワークになることはちょっと考えづらいですが、サーバーサイドSwiftがどのように動くのか、またそれはとても楽しいことだということをみなさんに伝える上で重要な役割を担うことができたら本望です
Slimaneは私が一人で作ってきましたが、コミュニティが作られる事を望みます。少しでもSlimaneに興味を持った方は私(yuki@miketokyo.com)に連絡をください。

# あとがき
作者の[Yuki Takei](https://github.com/noppoMan)さんは日本人なのでメールなどは全部、日本語で大丈夫なようです。興味があれば連絡を取ってみてください。