サーバーサイドSwiftとSlimane

  • 49
    いいね
  • 0
    コメント

前回、サーバーサイド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

1*ISCdTovumqqAuz0iNDj8vg.png

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

1*uilYwEJJGYxQm7Thg1BTXw.png

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

もっと試そう

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

チャットアプリとWeb Socket

https://cdn-images-1.medium.com/max/800/1*mlvR-iuux2Url96uaDDL_Q.gif

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

ブロッキングAPIとの共存

現在、私達のプロジェクトではMySQLはまだありません。ただ、心配しないで下さい 私たちは他のSwiftオープンソースソフトウェアであるZewo/Mysqlnovi/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

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
このコードはマスターとワーカープロセスの初期化をしています。(これはNode.jsのクラスターモジュールに少し似ています)

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
順番に異なるワーカーがリクエストを処理しています。

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

現状に関して

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

あとがき

作者のYuki Takeiさんは日本人なのでメールなどは全部、日本語で大丈夫なようです。興味があれば連絡を取ってみてください。