使いにくいScalaライブラリ

ScalaのHTTPライブラリってイケてないと思うんです。
何が気にくわないかというと、全体的にScalaのライブラリって、俺俺DSLを開発していて、
本当に使い方が分かりにくいと思うんです。

たとえば昔の Dispatch。(極端な例として、dispatch-classicのサンプルを記載します。)

// ex) http://dispatch-classic.databinder.net/URLs+and+Paths.html
import dispatch._
val sl = :/("www.scala-lang.org")
val learnScala = sl / "node" / "1305"

// ex) http://dispatch-classic.databinder.net/Response+Bodies.html
Http(learnScala >- { str =>
  str.length
})

もはやね。なんのこっちゃですよ。暗号ですか。
POSTリクエストを送りたくなってもどうしたらよいか全く想像がつきません。

私は、サンプルからオプションの使い方まで想像できるのが
使いやすいライブラリと考えています。

新しいDispatchではこのあたりは割と改善されているのですが、
ORMapperのSlick等も含めて、分かりにくい俺俺DSLを作り上げてしまうのはなんとかなりませんかね。
ライブラリの利用を通じて、タイプ量が少ない、Syntaxが短い事と、
シンプルで使いやすい事はイコールではない、ということを痛感しました。

AWS Lambdaで1分以上かかる処理をする

AWS Lambda、便利ですね。
サーバーレスでプログラムを実行できるのが魅力的なのですが、
実行時間が1分に制限される等、いくつかの制約で採用を見送る事もあるかと思います。

1分以上かかる処理はEC2等で実行しましょう、という事なのでしょうが、
どうしてもAWS Lambdaで処理させたい、というシチュエーションもあるかと思いますので、その制限を回避する方法を調査しました。

再帰呼び出しする

AWS Lambdaを起動するAPIが提供されているので、
LambdaスクリプトからLambdaを呼び出し、処理を引き継ぐことで、1分以上の処理を行うことができます。

var aws = require('aws-sdk')

exports.handler = function(event, context) {
  var count = event.count || 0
  count += 1
  console.log("count:" + count)
  
  // count が3を越えたら終了。
  if (3 < count) {
    console.log("count end.")
    context.succeed()
  } else {
    var lambda = new aws.Lambda()
    var params = {
      FunctionName: "recall",
      InvokeArgs: '{ "count": '+count+'}'
    }
    // countをパラメータに引き渡して自分自身のLambdaを再帰呼び出し。
    lambda.invokeAsync(params, function(err, data) {
      if (err) {
        console.log("error!")
        console.log(err)
      } else {
        console.log("next count:" + (count + 1))
      }
      context.succeed();
    })
  }
};

当然ながら、再帰実行する場合は、きちんと終了するフラグを立てるように実装しないと無限に再帰実行されます。
課金が発生するので、もしこの再帰Lambdaを実装する場合は慎重にテストしてください。
もし無限呼び出しが発生したら、Lambda関数の登録を削除する事で強制停止することは可能です。

また、Lambdaを実行するIAM Roleにlambda関係の権限を付与しておいてください。
(自動で作成されるlambda_basic_executionにはついていません。)

制約は多いものの、非常に安価にサーバーレスプログラムを実行することができるので、是非使っていきたいですね。

マイクロサービスの是非

巷ではマイクロサービスが流行っているようです。
モノシリックなアプリケーションに比べると、部分的なデプロイが容易になるなど、いくつかのメリットがあるようです。
すでに語られている内容ですが、個人的な見解をまとめておきます。

過去の経験としては、大規模になるにつれて、スケーラビリティや可用性を考慮すると、自然とマイクロサービスに近くなる気がします。
部分的にスケールアウトしたかったり、システム全体への影響のあるコード変更を避けたくなるからです。
多くの場合は以下のようなメリットを求めてマイクロサービスを採用するでしょう。

マイクロサービスのメリット

  • 部分的なスケールアウトを容易にしやすい。
  • コードの影響範囲を局所化してシンプルに保ちやすい。
  • 将来的に他のシステムから利用する可能性がある機能を切り出しておきたい。
  • 開発チームのパラレル化。

しかしちょっと待ってください。
一見、現代的な要求を満たしているマイクロサービスですが、
モノシリックなアプリケーションに比べると、多くのデメリットを潜在的に抱えています。

マイクロサービスのデメリット

  • 事前の設計如何によってコードが重複しやすい。
  • サービス間をまたがるリファクタリングがしにくい。
  • プロセス間通信によるオーバーヘッド。
  • 障害ポイントの増加→監視対象・運用作業の爆発。
  • デプロイ手順の複雑化。
  • テストの難度上昇。

特に運用面の問題は高確率で発生します。
モノシリックなアプリケーションに比べると設計の重要性はあがるでしょう。
(設計次第では、マイクロサービスのメリットを享受できない事もあるでしょうね)

本当の目的

個人的にマイクロサービス化するにあたり、重要だと考えているのは、以下の一点です。

  • システムの一部分が外部から利用される可能性があるのか。

「サービス」をマイクロ化しても、利用するのが同居するシステムのみの場合、
結局システム全体をデプロイするケースが多かったりして、あまりメリットが得られない事もあります。
マイクロサービスの採用を検討中の方は、この1点においてシンプルに考えてみても良いかもしれません。

VisualOpsいいですね

AWSの構成図をGUIで作成し、そのままCloudFormationのようにStackを構成します。
非常に完成度が高く、CloudFormationのJSONをエクスポートすることもできるため、JSONの手書きから解放されます。

ありそうで無かったので個人的に非常に助かります。

MVCについて 概念編

プログラミングにおけるMVCとは、Model-View-Controllerという概念に沿って開発するプログラミング手法の事です。
すでに語り尽くされているものですが、個人的なMVCに対する見解をまとめます。

Controller

一般的に、入力に対応するModelを呼び出す概念となっている。
入力パラメータによる分岐なども責務とされている事が多い。

複雑な分岐処理が多い場合、ファット(肥大化した)コントローラーとなり、見通しが悪くなる事が多い。
MVCへの理解が低い場合に、最もステップ数が多くなりやすい部分。

Model

いわゆるビジネスロジックを中心に、データやその振る舞いを実装する。
Ruby on RailsのActiveRecordのように、ModelとDAOが同一のものとして扱われる場合、
意識しないとビジネスロジックとデータアクセスのロジックが密結合になりやすい。

実装者の個性が特に出やすい部分。
チーム開発の場合は、まずModelの設計方針について検討するべき。

View

User Interface に関わる部分を実装する。
Controllerを呼び出すエントリポイント、Modelをどう表示するかを表現する。

Windows Formsであれば、FormやControlの表示位置、設定に関わる実装を行う。
Web ApplicationではControllerやModelから渡ってくるデータを元に表示用のHTMLを構成する。
最近であればデータをJSONやXMLに展開するだけのViewという形もよくある。

あまり実装者によって違いは出にくい層ではあるが、変更要求が最も多い部分であるため、
生産性、保守性を考慮して、テンプレートエンジンやレイアウト設計を検討する。

全体を通して

特にControllerとModelの責務が曖昧なため、採用するMVCフレームワークと実装者のスキルレベルによってはあっというまにスパゲティができかねません。
ロジックが特に複雑な場合は、Modelをデータ中心の層とロジック中心の層の2層にするなど、MVCの3層に拘らない方が良いというのが持論です。
Windowsアプリ等の場合は、ViewとControllerが一体化しやすい。ViewとControllerの間に1層増やすなどの工夫が後々効いてくることもあります。
考える範囲をコンパクトにするのがプログラミングの基本です。

10年以上MVCを採用したプログラムを書いてきているが、MVCは未だに廃れていません。
MVVMのように、MVCをより理想に近づけた手法も登場しているものの、実装が複雑なモデルは現場で採用しにくいのが現実です。
細かい部分を考えると問題も多いMVCだが、敷居の低い代替案も無いため、今後もMVCは主流のままでしょう。
とっかかりがシンプルなのがMVCの良いところかと思います。

今後、実装編等も書きたい。