「7日間で集まった5,000万人のユーザから学べるビッグデータの話」 (Azure ML blogメモ)

2015年10月28日水曜日

10月初旬、Azure ML blogでWhat 0-50 million users in 7 days can teach us about big dataという面白そうな記事が公開されていました。今回はこの記事をざっくりまとめてみます。

概要

多分おおかたの人が一度は見たことのあるサイトを題材にクラウドとビッグデータの話をするという内容です。
後半では、写真を若く見せるために大事なことが4つあり、
1. ヒゲを剃る
2. 笑わない
3. 眼鏡を外す
ということが明らかになります。

how-old.net

の話です。
いえ、
図1 how-old.net
https://how-old.net/(図1)の話です。
how-old.netはMicrosoftの//Buildというイベントと時期をあわせて公開された、Cortana Analytics Suiteが持つ顔認識APIのデモ用サイトです。
重要ポイントとして、このblogエントリでは
  • クラウドファーストで構築する
    • Webには、データ規模の小さなアプリをビッグデータなものへと変貌させうる力がある。大規模なトラフィックやストレージが必要となった際に自動でスケールしてくれるクラウドは最適
    • 開発自体をクラウド上でおこなうと、周辺サービスの活用によってサクサクつくれる
  • メトリックをリアルタイムで確認する
    • ユーザ動向をリアルタイムで把握してサービスに何が起こっているのかを把握するのはもはや必須
    • そのためにAzureではいろいろ用意してるよという話(App Insightsなど。リンクは原文参照)
  • クラウド上でのビッグデータ分析サービスを活用する
    • クラウド上のフルマネージドなサービスを使うことでビッグデータ分析が容易になる(Azure Data Lakeなどもふくめて)
  • 試して学ぶ
    • how-old.netはモバイルファースト・クラウドファーストで作ったことで開発稼働をあまりかけることなく迅速な実験を繰り返せた
が挙げられています。
わりとクラウド事業者の多くが話しているストーリーですが、今回の話の面白さは次に挙げる動画の側にあります。

動画

今回紹介したエントリ自体、実は著者のJoseph Sirosh氏が「Strata + Hadoop Worldというイベントのキーノートでこういうことを喋るよー」という予告エントリでした。
実際のキーノート映像もすでに公開されています。

このなかでは、how-old.netを公開してから得られた利用者の反応やこぼれ話などがユーモラスに展開します。
いくつか挙げてみます。
  • how-old.netの一般公開前に「blogやtwitterへ流さないように」との注意書きつきで社内向けに公開して反応を調べてみたら見事にTwitterへ流され、3時間で25,000人がアクセスしてきた
  • この時の反応を見てシェアボタンをつけたり、Twitterへ流す際のハッシュタグなどを検討して本番時に使った
    • 非ギーク向けにblogエントリを書きなおしたりもした
  • 本公開したら7日間で5,000万人が利用した
    • ピーク時には1時間あたり120万人が利用した
  • Twitterからスパム判定されてブロックされた
    • 問い合わせして復旧まで3日かかった
  • ひとびとが色んな遊び方をしてくれた
    • マーケターも食いついてきた
      • (注: 冒頭に貼った寿司ツイートはここから辿った)
  • 写真を若く見せるために大事なこと4つ
    • ヒゲを剃る
    • 笑わない
    • 眼鏡を外す
    • ????(ぜひ動画で確認してみてください!)
後半のアーキテクチャ面での重要ポイントとして4つ挙げているのは今回のエントリと同じですが、挙げられている中身は少し違ったりします(講演の内容でカバーされる部分があるためか)。
10分少々と短めで、わりと英語もわかりやすいのでオススメです。

about

このエントリは、Azure ML(Machine Learning)のblogから面白そうなエントリを掘り出してポイントをまとめるシリーズです。
前回: Azure Data FactoryのGA (Azure ML blogメモ)
次回: Visual StudioのRサポートで出来ること (Azure ML blogメモ)

Unreal Engine 4 ビデオチュートリアル記 #6

2015年10月24日土曜日

前回: Unreal Engine 4 ビデオチュートリアル記 #5
前回はゲームの機能群をBlueprintable Componentsへと切り分ける方法という話だった。UnityのPrefabっぽいものをワークフローへどのように組み込んでいくかという話で、実際に使っていかないと身につかないんだろうなという感じがした。

Blueprintでエンドレスラン系ゲームを作る #1

https://wiki.unrealengine.com/Videos/Player?series=PLZlv_N0_O1gbY4FN8pZuEPVC9PzQThNn1のランゲー作成をやってみる。Temple Runみたいなやつ。
  • ユーザは固定位置で走っていく
  • 障害物を避けたりアイテムを取ったりする
  • コースはどんどん自動生成する

イントロ

今回はイントロということで初期設定などの話。
12分ぐらい。
Third Personのテンプレートからプロジェクトを新規作成する。
このチュートリアルが収録された頃にはまだブルーマンだったんだなぁと思いながら作成(図1)。
図1 ブルーでなくなってしまったマン
続いて、キャラクターのBPを開いてゴリゴリといじっていく。
デフォルトで生成されているBPのうちで今回不要な分を削除していく。固定位置のランゲーを作るのでGamepad、タッチ入力、マウス制御が不要ということで削除。
キー入力イベントからRotatorをいじって指定時間かけて指定角度の回転をおこなうあたりはイディオムだなーという感じ。
これに方向転換を許す領域としてコライダーを追加して内部の方向転換可否フラグを書き換え、そしてコライダーとの干渉後に一度方向を変えたらもう変えられないように方向転換可否フラグを落として終了(図2)と。
図2 方向変えられるようになったマン
12分のビデオだけど所要時間は45分ぐらい。メモを取ったりスクショを撮ったりとしつつだけど、結構わたわたとしてしまうので大事なポイントを把握して脳内で手順を再構築できるようになってないんだなーと思う。
次回はステージを作るらしい。

C#でSORACOM APIのモックを作ったよー。ついでにC# 6+ASP.NET 5で楽にRESTfulサービスを書けてオススメという話

2015年10月23日金曜日

APIモックを作る?

SORACOM APIをC#から触れるようにしたのとおり、先日SORACOM APIの非公式な.NET版クライアントライブラリを書きました。
これについてソラコム Developers Conference #0のLTでひたすら「API sandboxがないので管理クライアントや他言語SDKの開発がつらい」という話をしてから1週間ほど経ちます。
「よーし足りないAPIを追加するかー」と思ったものの、やはり最低限はテスト環境が無いとリグレッション検出などで結構困るので、テスト用のモックサービスを作ることにしました(手間がでかすぎてyabaiというほどでもないし)。
試験前に部屋の片付けをするノリで作ったので本当に最低限だけです*1が、完成したので
置いておきます。本家でsandboxがリリースされたらひっそりとクローズすると思います。
ともかく、心置きなくSIM解約のテストができるの素晴らしい!
以下は、作り方が気になる方のための簡単ASP.NET 5ガイドです。
[*1] パスワード指定ポリシーは本家のAPIに準拠したりしていますが。

構成

  • 開発言語: C# (C# 6)
  • フレームワーク: ASP.NET 5(ASP.NET MVC 6 beta5)
  • 開発環境: Visual Studio Community 2015
  • 稼働環境: Microsoft Azure Web Service(Web Apps無料版)

ASP.NET 5(ASP.NET MVC 6)でRESTfulサービスを作る

ASP.NET 5とDNXの1.0.0-beta8がリリースされてたで書いたようにASP.NET 5はfeature complete状態にあります。つまりコードの安定性はさておき、現時点で提供されているAPIセットはよほどのことがない限り製品版まで変更されないはずです。最悪落ちても辛くない系プロダクトを書き始めるのにちょうど良いタイミングということです。
基本的にVisual Studio 2015(以下VS2015)のASP.NET Web Application内にあるWeb APIテンプレートから作成したものを下地としてリファレンス片手にIntelliSense眺めつつ気合で書き換えていきますが、取っ掛かりとしてはBuilding Your First Web API with MVC 6が良いチュートリアルです。

VS2015でのASP.NET 5 Web Application(preview)プロジェクト作成

VS2015に含まれているASP.NET 5のプロジェクトテンプレートは多少古く、beta5用のものです。
じきにVS自体のアップデートで更新されると思いますが、現段階ではひとまずbeta5を使っておきましょう。
project.jsonの中身を直接書き換えて依存関係を更新する策もありますが、これを書いている時点ではMicrosoft.AspNet.Server.IISだけbeta8版が出ていないので、更新待ちです*2
[*2] 軽い気持ちで混ぜたところやっぱりダメだったので混ぜるな危険。どうしても新betaを使いたければIISをやめてKestrelを使うなど、手はあります。それはそれでハマりそうですが。

レスポンスの返し方について少々メモ

プログラムにエラー処理はつきものです。
当然、RESTfulなAPIでもさまざまなエラー処理が必要です。
Visual Studioのテンプレートから生成されるValuesControllerは普通に各APIからの戻り値をstringIEnumerable<string>と宣言します。こうしておくとASP.NET MVCのランタイム側で適当にJSONへ詰め込んで返してくれます。
このフローは型情報をきっちり書く面ではとても良いのですが、不便なところがあります。HTTPのエラー情報を返すうえで厄介なのです。
従来のASP.NET MVCではこの処理に例外を使っていました。
throw new HttpResponseException(HttpStatusCode.NotFound);
という具合です。
しかしASP.NET 5でこのように書いても単純に内部でハンドルされていない例外が発生した扱いとなるだけです。
ではどうするのかというと、レスポンスをラッピングできるIActionResultというインタフェースに従った値を返すようにします。
HTTPのエラーコードはいろいろありますが、要はテンプレコードです。なるべく省力でカバーしたいものです。
たとえば400のbad requestを返したい場合、ASP.NET MVC的にはBadRequestResultBadRequestObjectResultのふたつの選択肢があります。レスポンスのボディがあるか無いかという違いを考えると、このようにわかれているのは仕方ないのですが、呼び分けるのが微妙に面倒です。
ASP.NET MVCのControllerは至れり尽くせりで、HttpBadRequestというstaticメソッドがオブジェクトを引数として渡すか否かで生成オブジェクトを切り替えてくれます。
これを使って次のようにサクサクとエラー処理を書けます。
  [HttpGet]
  public IActionResult Get()
  {
    return HttpBadRequest(new { foo = "shinchoku", errmsg = "damedesu" });
  }
このあたり詳しくはASP.NET MVC自体のコードを読むのが早いです: https://github.com/aspnet/Mvc/blob/f57e1809716/src/Microsoft.AspNet.Mvc.ViewFeatures/Controller.cs#L970-L1009

粛々とAPI仕様に従ってコントローラを書く

書きます。
最初のうちは動作確認をcurlでおこなっていましたが、途中からFiddlerへ変更してサクサク確認していきました。IEからの通信を自動キャプチャとかとても便利でした。

ASP.NET 5(ASP.NET MVC 6)でサクサクとWeb APIを作る

ASP.NET MVC 6ベースのRESTful API構築は割と生産性高くて良いです。面倒なボイラープレート系のコードはほとんどなく、コーディング時間のうちほとんどをAPI定義→C#コードへの翻訳に使えました。
RESTfulなサービスにおいて、HTTPのリクエストではおおまかに
  • URIのパスにfoo/bar/hoge/fuga形式で記述
  • クエリ文字列に?foo=bar&hoge=fuga形式で記述
  • リクエストボディにJSON({"foo":"bar", "hoge":"fuga"})で記述
とあり、それぞれが結構楽に扱えるようになっています。
今回はクエリ文字列解釈を使っていませんが、それ以外のふたつは
  public class SetGroupRequest
  {
    public List<string> configuration { get; set; }
    public long createdTime { get; set; }
    public string groupId { get; set; }
    public long lastModifiedTime { get; set; }
    public string operatorId { get; set; }
    public Dictionary<string, string> tags{ get; set; }
  }
  [HttpPost("{imsi}/set_group")]
  public IActionResult Post(string imsi, [FromBody] SetGroupRequest req)
  {
    ...
  }
(https://github.com/muojp/SoraCommonNet/blob/master/SoraCommonNetSandbox/Controllers/Subscribers.cs#L145-L155からの抜粋)
というようになります。
  • URIパス内の特定部分に名前をつけて受け取る
  • リクエストボディのフォーマットを規定したら[FromBody]属性をくっつけて受け取る
というのをさらっと書けています。
前述のエラー処理に関するポイントと共におさえておくと、楽にサービスを書き始められると感じました。
C# 6のNull conditional operatorもhttps://github.com/muojp/SoraCommonNet/blob/master/SoraCommonNetSandbox/Controllers/Subscribers.cs#L40のような場所で役に立ちますね。

テストのテストをどうするかという話

Ruby版SDKなど、他言語用のバインディングを使ってテストする策がありますが、今のところこれ自体のテストは書いていません。

適当にデプロイして様子を見る

どうせ誰も使わないので適当に公開しておきます。
Azure Web Serviceの無料版はSSL非対応なのでhttpのみです。またこれは所詮モックで、SoraCommonNet側のコミットフックなどでのテスト実行時のみに利用するものなのでquota的な問題はないでしょう*3
ちなみにこれは無料プランゆえのtipsですが、自動テストから叩く際にはSetUp的なメソッド内で適当なAPIを叩いてスピンアップさせるのが無難です。さもないと序盤のテストケースで10秒程度固まり、標準の2秒タイムアウトだと何かと面倒な感じになるでしょう。
[*3] 無駄に検索エンジンから拾われるのもアレなのでrobots.txtぐらいは置いておいたほうが良いのかもしれません。

Effective Objective-C 2.0 読書メモ #21

前回: Effective Objective-C 2.0 読書メモ #20

Item 21: Understand the Objective-C Error Model

前回はプライベートメソッドにはプリフィックスをつける(ただし_はAppleのものと被って事故るので避けるように)という話でした。
今回はObjCのエラー処理モデルを理解するという話です。

例外処理機構について

  • ObjCにも例外機構は存在するが、基本的に復帰不可能・即終了のパターンでのみ使うべき
    • ARCの標準状態は例外セーフではないのでメモリリークを発生させうる
    • -fobjc-arc-exceptionsフラグをつけてコンパイルすることでこれは回避できるが、これをつけると正常コードパスでも余分なコード実行が必要になる
    • リソースの解放前に@throwをおこなうとリソース解放コードは呼び出されない
  • 例外を効果的に使えるケース
    • サブクラス実装の強要: サブクラスで必ずオーバーライドすべきメソッドをオーバーライドしなかった際の親クラス実装で例外を吐き、実装漏れをすぐに認識できるようにする
      • abstractの言語サポートがないので有用という話

例外以外のエラー処理の方法

  • デリゲートメソッドでエラーを受け取れるようにする
    • こうするとエラー情報を処理するかどうかの決定をユーザに委ねられるので例外利用よりだいぶよい
  • メソッドからの戻り値を0nilとしたり、NSErrorを使ったりする
    • NSErrorを使う場合、メソッド自体はBOOLなどを返すようにする
    • NSErrorerror domain@error codeuser infoという3つの情報を返せるので使い勝手がいい
  • ARC下では関数内でNSError**を作ってもautorelease対象となるため返せない
    • これでは困るので呼び出し側からNSError**を渡して関数内で値を突っ込む方針でいく
  • ライブラリの専用NSErrorを用意して区別つくようにしたり、ヘッダにコメントを書いたりするとなおよし
とてもすっきりな話だった。

ASP.NET 5とDNXの1.0.0-beta8がリリースされてた

2015年10月22日木曜日

2週間ほど前に最近のASP.NET 5について調べたメモ(2015Q4)を書いたタイミングではまだ出ていなかったASP.NET 5およびDNXのbeta8がリリースされていました。
調べてみると1週間ほど前にリリースされていました。https://github.com/aspnet/dnx/milestones
図1 DNX 1.0.0 beta8を入れた

beta8?

なぜわざわざbetaリリースでエントリを書くかというと、ASP.NET 5のロードマップ中でbeta8は最後のbeta版と位置づけられているためです。
このあたり、時系列では
  • beta8までに機能追加系はすべて完了
  • 安定性を高めたRC1版を来月(2015/11)中にリリース
  • その後は適宜RCを重ねて2016年のQ1(1-3月)に正式リリース
ということになっています。
つまりSignalR 3などのASP.NET 5初期リリースからオミットされてしまった要素を除けば全部実装済み!という状態ですね。

これ完成するのかなという不安

サーバ環境での完全なSxSデプロイ*1はASP.NET 5の目玉のひとつで、その完成度は.NET Core(CoreCLR+CoreFX)の完成度に大きく依存します。
CoreFXの完全NuGet主義なフレームワークコード開発はだいぶ進んでいますが、CoreCLRのクロスプラットフォーム実装はまだまだ発展途上にあります。どれぐらい発展途上かというと、CoreCLR版のDNXでASP.NET 5のシンプルな公式サンプルをいくつかいじり回すだけでボコボコとクラッシュするような状態です。
個人的にこれはstabilizeという領域のだいぶ手前にあるように感じられます。明らかに無理な*2スケジュールを押し通したUnity Technologiesぱいせんなども世の中にはいるので、短期間に完成度を上げるのも不可能ではないと思いますがMicrosoftがCoreCLRの完成に向けて極端な量のリソースを投下して頑張るかというと現状そんなインセンティブのあるエリアでもないはずです。
クロスプラットフォーム実行に関してMicrosoftは「Monoを一切使わずCoreCLRのみで実行する」なんてことは言っていないので、非Windows環境のCoreCLRバグは割と放置したまましれっと-runtime mono状態でリリースするのでは、というのが今のところの見立てです。
つまり極端な話OS X上のCoreCLRで動作するDNX上でASP.NET 5のコードが一切動かない状態でもリリースは可能と。
とはいえ、そろそろバグを見つけたら可能な限り切り分けてせっせとissueを作っていくフェーズには来てるのかなーという気持ちの高まりを感じたbeta8リリースでした(前回書いたように、私はDNXベースでクロスプラットフォームなツールをほいほいと作っていきたいので)。
[*1] ここでは複数バージョンのフレームワークをお互いに干渉させることなく同一環境へ同居させて使い分けられる仕組みを指します。
[*2] IL2CPPによる64-bitサポートをAppleのデッドライン付近でひとまずの着地まで持っていったのは本当に凄いと思います。

すごいHaskell 読書メモ #3

前回: すごいHaskell 読書メモ #2
前回はデータ構造の序盤ということでリストの話と内包表記の話などでした。

タプル

今回はタプルです。タプル自体は他の言語でも馴染み深いものです。

メモ

  • タプルのリストを作る際に異なるシグニチャのものを混ぜてはいけないというのが新鮮に感じた
    • 前回やったリストのポリシーを考えると「リストは特定の型の要素の列」ということなのだから当然だった
  • 2要素のタプルはペアとも呼ばれ、3要素のタプルはトリプルとも呼ばれる
    • ペアに対して先の要素と後の要素を取り出すfstsndという関数は頻出らしい
      • 名前的には覚えやすい
    • トリプルから同様に値を取り出すものについてはちょっと後で出てくるとのこと。
  • リストはサイズの違うもの同士で比較できるのに対し、タプルは同サイズ同士でしか比較できない
  • zip便利だなぁ
    • ふたつのリストから組にして値を取り出してペアのリストにするというオペレーション結構よく使いそう

演習問題

直角三角形の問題は、
ghci> [(x,y, sqrt(x^2 + y^2)) | x <- [1..10], y <- [1..10], sqrt(x * x + y * y) + x + y == 24]
[(6.0,8.0,10.0),(8.0,6.0,10.0)]
と強引に解きました。解法を見たら泣けるほどきれいにフィルタリングで条件を詰めていっていてそれっぽかった。
c <- [1..10], b <- [1..c]などの値の持つ性質を反映したリストを作るというのは結構大事なポイントになるんだろうな。
多少手が動くようになってきたところで今回は終わり。次回は第2章「型を信じろ!」の話です。

Azure App Service上のC#バッチからNode.jsベースのコマンドをさらっと叩く方法(おいしいnpmモジュールの淹れ方)

2015年10月21日水曜日

Azure App ServiceのAzure Web Apps(WebJobs)、なかなかいいです。
AWSのLambdaと似たいわゆるサーバレスなアプリケーションコードホスティングの仕組みですが、特性は割と違います。
  • AWS Lambdaは基本パッケージを50MBに抑えたプログラムを頻繁にデプロイ・破棄する構造
    • さもなくばプログラムの起動後にS3などから別途データを拾ってきて展開する(そしてtmp容量は512MBに制限されている)
    • 利用できるメモリ容量をプライマリとしてそれにCPUリソース量も紐付いた料金体系
  • Azure App Serviceは原則的にリソース予約版がメインで、共有リソース版(Lambdaのような動的アプリ展開版)はおまけ扱い
    • 共有リソース版でも最大1GBという比較的大きなアセンブリ群をホストして比較的低頻度デプロイをする想定
    • Lambdaのようにms単位でのコード実行とは謳わない
    • (個人的にはもっと共有リソース版のプラン種類を増やしてほしい)
実行ノードからアプリがアンロードされた状態からのデータロードと処理実行は、きちんと計測していませんがLambdaのほうが体感速いです。
このように実行モデルが異なるので直接比較はできませんが、Azure Web Serviceは小規模・リソース共有版なら1日あたり60分のCPU利用まで無料で使えます。こまごましたバッチを試作するのにうってつけです。

Azure上でC#とNode.jsのいいとこ取りをしたい

Node.jsというかnpm上には豊富なパッケージが存在します。
なかにはNuGetに同等のものがあるものも存在しますが、Node.js界隈に特有のものやNuGetを探すのが面倒なものも多くあります。
最近はAzure Web AppsのWebJobs(指定URLのキックによる逐次処理、定期バッチ処理、継続実行処理のデプロイモデルを選べる)を使ってバッチを書いているんですが、その中でnpm配布されているコマンドを使いたい場面がありました。餅は餅屋というわけで、Node.js方面でコマンド提供されているものを簡単にC#(.NET)から呼び出していいとこ取りをしようというのが今回の話です。

Azure Web AppsでのNode.jsサポート概要

そもそもAzureでNode.jsをまともに使えるのかという話から始まりますが、しっかり使えます。
Node.jsのバージョンはデフォルトで「アプリケーション設定」内にある設定(この場合は0.10.32)が使われますが、かなり多くのバージョンをサポートしています。
このあたりはAzure アプリケーションでの Node.js のバージョンの指定で詳しく書かれています。
今後もきちんと増えていく雰囲気です。
あっ、Azure Web Appsで実際にNode.jsが実行される環境はWindowsマシン上です。それがどうしても許せない人は諦めてください。

Node.jsベースのコマンドをインストールする

ここでは、JSONファイル同士のdiffをいい感じに出力してくれるjson-diffモジュールをインストールしてみます。
Azure Web Appsの提供するSCMへアクセスし、「Debug Console」を開きます*1
デバッグターミナルが表示されるので、npm install json-diffを実行します。
図1という具合で文字出力が一部化けて残念な感じになっていますがインストール処理は完了します。
図1 npmでのモジュールインストール
ここでnpmモジュールをインストールしたD:\home\node_modules以下のデータは、該当する処理を実行しているVMのローカルストレージではなくAzure Web Apps構成データとして保存されます。このため、割り当てられたVMが変わったりアプリのプランを変更した場合でも再度npm installをおこなう必要はありません。
[*1] https://(アプリ名).scm.azurewebsites.net/DebugConsole でアクセスできます。

C#コードからnode.jsベースのコマンドを呼び出す

試しに適当なJSONファイルとしてD:\home\node_modules\json-diff\package.jsonD:\home\node_modules\json-diff\node_modules\cli-color\package.jsonの差分を出力してみましょう。全く違うnpmパッケージのpackage.json同士なので、大量のdiffがあるはずです。
C#からの外部プロセス作成は通常通りSystem.Diagnostics.Processを利用します。
  var proc = new Process
  {
    StartInfo = new ProcessStartInfo
    {
      FileName = @"D:\home\node_modules\.bin\json-diff.cmd",
      Arguments = @"""D:\home\node_modules\json-diff\package.json"" ""D:\home\node_modules\json-diff\node_modules\cli-color\package.json""",
      RedirectStandardOutput = true,
      UseShellExecute = false,
      CreateNoWindow = true
    }
  };
完全なコードはこちら: https://gist.github.com/muojp/bb677aea6021e2a7cfaf
これを実行すると、
...
[10/20/2015 12:43:33 > 123c4b: INFO] -  _id: "json-diff@0.3.1"
[10/20/2015 12:43:33 > 123c4b: INFO] +  _id: "cli-color@0.1.7"
[10/20/2015 12:43:33 > 123c4b: INFO]    dist: {
[10/20/2015 12:43:33 > 123c4b: INFO] -    shasum: "6dbc3ae2d25e075a7fd71bcd9874458666fb681b"
[10/20/2015 12:43:33 > 123c4b: INFO] +    shasum: "adc3200fa471cc211b0da7f566b71e98b9d67347"
[10/20/2015 12:43:33 > 123c4b: INFO] -    tarball: "http://registry.npmjs.org/json-diff/-/json-diff-0.3.1.tgz"
[10/20/2015 12:43:33 > 123c4b: INFO] +    tarball: "http://registry.npmjs.org/cli-color/-/cli-color-0.1.7.tgz"
[10/20/2015 12:43:33 > 123c4b: INFO]    }
...
という感じでJSONファイル同士のdiffが出力されます。
正しいアプリベースディレクトリの取得方法がわからなかったのでD:\home\node_modulesを決め打ちしています。
このパスが変わることはひとまず無いはずですが、https://(アプリ名).scm.azurewebsites.net/api/vfs/ へアクセスして出力されるディレクトリ一覧からnode_modulesを探してくるのが正攻法な気もします。
正しい指定方法をご存知の方いらっしゃいましたら教えて下さい。

まとめ

Azure Web Apps上でnpmからNode.jsベースのコマンドを拾ってきてC#(.NET)から呼び出すのは結構簡単なので、手軽に使えそう。

Re:VIEW文書中でblockdiagを使ってサクサクと図を描く

2015年10月17日土曜日

文書になるべく図を入れたいけれど

Re:VIEWで文章を書いていてサッと図を入れたい場面、結構ありますよね。
けれど{Photoshop|Illustrator|GIMP}を開くのが面倒で、結局文字だけでの説明をしてわかりづらくなる場合も多いのではないでしょうか。
図1

Re:VIEWよくできてんな

Re:VIEWはビルトインでgraphという記法をサポートしています。
グラフ表現ツールを使った図に記載のとおりgraphvis、gnuplot、blockdiagをサポートしています。
ここではプレーンテキストでブロック図を作成できるblockdiagを使ってみました。

blockdiagのインストール

Re:VIEW側は環境にインストールされたblockdiagコマンドを叩くだけなので、予めこれをインストールしておく必要があります。
OS Xでのインストール方法はhttp://blockdiag.com/ja/blockdiag/introduction.html#macosx-homebrewのとおりです。
基本的に
$ brew install freetype
$ sudo easy_install blockdiag
で終わります。

Re:VIEW上でのblockdiagの基本

//graph[図ID][blockdiag]{}の間にblockdiag本来の記述をおこないます。
作図で使える記法はhttp://blockdiag.com/ja/blockdiag/examples.htmlに記載されていますので参照ください。
冒頭の図は、次のようにさまざまな要素てんこ盛りで作ってみました。
blockdiag {
  default_shape = roundedbox;
  default_fontsize = 12;
  ちょっと図が欲しい -> Photoshopを開くのが面倒, Illustratorを開くのが面倒, GIMPを開くのが面倒 -> 図を端折る -> 分かりづらい説明 -> 分からない!;
  図を端折る -> 分かりづらい説明 [folded];
  group {
    分からない!
    label = "危険があぶない";
  }
}
基本的には要素間を->でつないでいくだけです。
図への参照は通常どおり@<img>{...}でおこなうと 図1 というように変換されます。

便利!

これは標準ワークフローに組み込んでもいい感じの便利さですね。

かなしさ

Atom+language-review環境はgraphを今のところサポートしていないので、図2という悲しい感じになります。文法エラー扱いということはもちろんプレビューも全体的に効かなくなるので、ふんわりとどうにかしたいところです。


図2 language-reviewでgraph要素を書くと

SORACOM APIをC#から触れるようにした

2015年10月16日金曜日

宣伝

.NETからSORACOMのAPIをさらっと叩ける非公式SDKをつくりました。
https://github.com/muojp/SoraCommonNet
気になる点があればふわっとissueに書いて頂けるとうれしいです。
本エントリでは、この開発中に使ったツール類や方法論、より深くSORACOMに触れてみて得たものなどをメモします。

イントロ

届いたSORACOM、さーてどう使おうかなと思って公式の開発者向けWebサイトを眺めていたら「.NET用SDKないじゃん!」と気付いて呆然としたところからスタートしました。せっかくなのでサーバから手元の携帯電話まで、広い環境で動作するプロファイル(PCL)で書くことにしました。
3マスすすむ。

ここまでやった

ひとまず昨晩ごりごりと作って
  • Operatorの新規登録(仮登録メール送信〜登録確認まで)
  • Operatorとしてのログイン
  • トークン更新
  • Subscriber(SIM)の一覧取得
までできるようになったのでNuGetへ投下しました。
逆に
  • Subscriber(SIM)の絞込検索
  • グループ管理
  • イベント管理
あたりはまだ書いていません。
せっせと作り進んでいく途中、Subscriber(SIM)のアクティブ化/非アクティブ化あたりで公式ドキュメント上のTry it out!機能から叩いてもエラーを吐くものをいくつか見つけた時点で一旦心が折れたので実装はそこまでになっています。
あっ、今回はなるべくRuby版のコードは無視して公式ドキュメントのみで書いてみる縛りでやってみました。初見時からときおりドキュメントに怪しい部分があると感じていたのですが、これに沿って実装することで抜け漏れを洗い出せた気がします。

SORACOM Beam開発者の友、Runscope

SORACOM Beamは「SORACOM Airからの通信をソラコムのゲートウェイで受けて適宜プロトコル変換、ヘッダ付与のうえで他のサーバへ投げ直す」という仕組みです。
こう聞くと、どんなヘッダがついてくるのか、署名データはどのようなものなのか気になって実際にサクッとHTTPリクエストのログを取ってみたくなりますね。
しかしまあサーバを立ち上げてリクエストロガーをこさえて待ち受けるなどするのは結構面倒です。
このエリアで「発行されたURLへHTTPリクエストを投げると、その内容を記録して後から調べられるようにしてくれる」というスナックなサービスとしてrequestbinが有名です。
しかし残念ながらrequestbinはHTTPSでのデータ送信をサポートしていないようです。少なくともSSL証明書の真正性検証まわりでエラーを吐くので、ゴリ押しで実行してもデータ送信側サーバのポリシーによっては接続確立させない可能性があります。今回の用途ではひとまず避けるのが無難でしょう。
そういうわけでHTTPSをきちんと通せる代替サービスを探してみました。
https://www.runscope.com/がこの用途にぴったり合いそうです。
14日トライアル後の料金を見ると月$79と結構な額するのでびっくりしますが、実は「トライアル期間後も月間25,000リクエストまでは無料で使えるので安心してね」と書いてあります。
図1 RunscopeでSORACOM Beamの中継結果をダンプ
とても便利ですね。
SORACOMにはsandboxがないので、実際のIMSIなどを含む情報を第三者のサーバへ渡しつつ開発することになるのが嫌な気もしますが、そういう際にはRunscope自身が提供しているrequestbinのソースを使って自前で立てるのが良いと思います。
共有のワイルドカードSSL証明書が導入された環境を用意して…と相応に手間ですが。
MQTTや生TCPプロキシ機能あたりも考えていくと、かしこいBeam対向サーバソフトウェアの需要は一定ある気がしますね(署名検証のみやって既存ソフトへ渡すラッパでも良いはず)。

SORACOM Beam開発者の友、Windows Phone端末(MADOSMA)

WPのデータセンサー機能がなかなか良いよという話です。
SORACOM側でのIMSI付与および署名付与を使うためには、当然SORACOM Airからリクエストを発生させる必要があります。
SIMが刺さっていて、おとなしい(バックグラウンド通信をガンガンしない)環境が必要です。
Androidについてひつじが頑張ってたのでそれで、と思ったのですがたまたま手元にあるAndroid 5.x端末のSIMスロットの調子が悪いので、別解を求めて0.2里というところです。近いですね。
手元にある中でなるべくバックグラウンド通信が静かな端末を探したらMADOSMAだったので、こいつに挿してちまちまとアクセスすることにしました。
さて、Windows Phoneにはデータセンサーという機能があります。モバイルネットワークの通信量を制御したり、バックグラウンド挙動に制限を加える機能です。
Windows Phoneは高速ネットワークが一般的でない地域でのシェアを得るためにか、本機能をなかなかよく作り込んでいます。通信量制限の基本設定をおこなえば、あとはスイッチひとつで基本的にバックグラウンド通信をごっそり遮断できます。システムアップデートの自動ダウンロードも選択式(デフォルトは無効化された状態)なので、気付いたら100MB゚(゚´ω`゚)゚。ピーということが多分ありません。
図2 Windows Phone 8.1のデータセンサー
もちろんiOSなどにも似た機能はあるのですが、iOSの場合は「モバイルネットワーク利用を認めないアプリをひとつひとつスイッチでオプトアウトしていく」という途方も無い作業が必要です。それに、iOSはシステムサービスが相応にデータ通信をおこなっています。
そこで、どのご家庭にもあるMADOSMAの登場です。
今回、SORACOM Beamの動作確認には「Runscopeで発行したURLをSORACOM Beamの転送先エンドポイントとし、SORACOM Beam側エンドポイントURLをいじったら適宜QRコードを生成してMADOSMAで開く」というフローをとりました。
ここでのポイントはMacなどからMADOSMA経由のテザリングアクセスをしないことです。特にMacのMac App Storeなどは「Wi-Fi環境だ!わっほーーーい」という具合に無慈悲なアップデートをおこなったりするので、気付いたらデータ転送量がアホみたいに膨らんだりします。
Macからcurlを叩いてリクエスト検証をしたい場合には(デフォルトルート指定に気をつけつつ)Wi-Fiとは別にBluetoothテザリング経由で携帯端末にアクセスするなどの工夫が必要でしょう*1
[*1] これはUSBドングル形式の3G/LTEモデムを利用する場合でも同じです。接続順などでデフォルトルートを書き換えられないよう、あるいはそれを上書きするように一定注意すればなんとかなるでしょう(そしてたまに事故る)。

APNのプロキシ設定でいい感じに足回り整備できないかの検討

SIMに対するAPN設定欄にはプロキシサーバの設定項目があります。一時期はWeb閲覧高速化プロキシをここに指定することでWebブラウジングが快適になる、という使い方をちらほら見ました。最近は通常事業者側の透過プロキシで処理されるためあまり見かけませんが。
このプロキシサーバ設定で自前のサーバを指定し、不要なアプリの通信やOSアップデートなどのリクエストを遮断できるのでは、という指針です。
おそらく、一定はできると思います。OSのアップデートファイルダウンロードあたりを止められるかはわかりませんが、基本的にアプリケーションのトラフィックを流せるようになりますし。
この場合、プロキシに指定するのは開発者自身が用意したサーバとなります。このためSORACOM Airでこの仕組みを使うと、相応のものを失うことになります。SORACOM Beamが持つ「低負荷なMQTTや生TCPをセキュアなプロトコルに変換しておたくのサーバに届けるよ」というおいしい仕組みを利用できないというつらさです。
beam.soracom.ioへのトラフィックのみプロキシを介さずに処理できれば両立できそうですが、APNへのプロキシ設定に例外ホストを指定できる環境を見たことがないので、多分無理なのではないかなと。
ということで一長一短ありますね。常用しているAndroid端末からのほとんどのリクエストを叩き落とす系の用途には使えそうなので、ネタとしてストックしておいてよさそうですが(相応のプロキシサーバを用意しないとフィルタリングも結構たいへんじゃないかなぁ)。

.NET的な事情

今回書いたライブラリはWindowsサーバ上でもMac上でもAndroid/iOS/Windows Phone上でも動かしたかったので、PCLにしました。
PCLで扱えるREST APIへのアクセスライブラリは割とどれも一長一短あるのですが、PortableRestを使いました。これは、以前Pivotal Trackerへのアクセスライブラリに手を入れた際に試してみて「完全ではないけれど事足りる」とわかっていたためです。
PortableRestの厄介なところは概ね以下のとおりです。
  • ステータスコードを取得するのが結構大変
  • エラー(4xx、5xx)が戻ってくると容赦なく例外を吐いてレスポンスボディを捨てるので「400を返しつつヒント情報をレスポンスボディで戻す」ようなAPI(SORACOMもこれ)との相性がかなり悪い
ドキュメント(たまに間違ってる)を読みながらゴリゴリと実装していくパターンとの相性は、あまりよくありません。PortableRestは1年以上バージョンアップが止まっているし、そろそろこのライブラリ自体に手を入れたほうが良いのかもという気もしています。
ちなみに
  • multipartリクエストにおいて複数ファイルのアップロードをサポートしていない
という問題もあるのですが、SORACOMのAPIを叩く分には関係ありません。

作ってる途中で見つけたドキュメントの怪しい点

そもそもSDKドキュメント内のTry it out!から叩いても普通にエラーを吐くAPIがある

たとえば/subscribers/{imsi}/enable_terminationで、IMSIを指定して実行するとサーバが400を返してきます。
{
  "code": "SEM0003",
  "message": "Bad request: Invalid Json"
}
という具合です。
  • /subscribers/{imsi}/disable_termination
  • /subscribers/{imsi}/activate
  • /subscribers/{imsi}/deactivate
あたりも同様です。
どうもJSON本体を持たない系リクエストが失敗している風味があるので、ひょっとすると空ボディでも食わせればうまくいくのかもしれません。
おそらく実装的にはRuby版SDKの中身を読んでそれに合わせるのが手っ取り早いです。

/subscribers/{imsi}はドキュメントに記載されている項目よりもたくさん値を返してくる

以下が増えていました。ドキュメントを書いた後で増えたのかもしれません。
  • groupId
  • terminationEnabled
  • sessionStatus
  • moduleType
  • plan
なお、ドキュメントされていないsessionStatusは未使用SIMではnullを返します。そのSIMを使い始めた後には戻ってくる値が変わり、ネストした要素でimeiなどの値を持つようになります。
登録済み・未使用状態のSIMを使ってSDK開発をおこなっている際には気付かず、後から念のためテストを一回しした際に見つけて「ヒッ」となりました*2
[*2] その後、ひとまずhttps://github.com/muojp/SoraCommonNet/commit/09e8c9037でワークアラウンドを入れました。じきにちゃんとスキーマを書くと思います。

/operators/{operator_id}/token の戻り値がドキュメント記述と異なる

ドキュメントには
GenerateTokenResponse {
  apiToken (string, optional)
}
と書かれていますが、実際はtokenというキーで戻ってきます。しばしハマりました。
追記(2015/10/29): 10/27のドキュメント改訂で直っていました

作ってる途中で湧いた疑問

ちょうど今日SORACOM Developers Conference #0があるので、そこで聞こうという備忘録も兼ねてメモ。
  • Beamでtcpを使った場合、課金用のカウントはどのようになる?
    • パケット数でカウント?HTTPはリクエスト単位?戻りがchunked-transferとかなったらどうなる?
  • SORACOM BeamでIMSI ヘッダ付与署名ヘッダ付与として事前共有鍵を指定した場合の署名検証の方法
    • X-Soracom-Signatureを見る限りはHMACSHA256っぽいけれどさすがに値の食わせ方が分からないとムリなやつでは
    • key=<事前共有鍵> imsi=<IMSI> timestamp=<Timestamp>などいくつか試してみたけれどハズレだった
      • TCP→TCPなど、リクエスト全体が事前に分からない場合でも(おそらく同じ手順で)署名検証できるということは基本的に事前共有鍵+ヘッダ内の情報のみで計算できるはずなのだけど
  • /operators/{operator_id/token}のtimeout_seconds、元トークンよりも長い設定をしても受けない(つまりauth時に指定した間隔以下でしか受け付けない)ようになってたほうがセキュリティ的には都合よいのでは?
X-Soracom-Imsi: 11112222XXXXXXX
X-Soracom-Signature: 31XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXf4
X-Soracom-Signature-Version: 20150901
X-Soracom-Timestamp: 14449XXXXXXXX

作ってる途中で湧いた要望

書いているあいだじゅう、sandboxがないのでTermination(SIM解約)コマンドとかほいほいとテストできないことがとてもつらかったです。
ということで、いくつか要望をまとめました。これも今日のSORACOM Devel(ry
  • sandboxがほしい
  • sandboxがほしい
  • sandboxがほしい
  • Subscriberの無効化とかは適当にイベントAPIから流してほしさがある(完全性確保は求めないとしても)
    • 加えて、イベントはInvokeAWSLambdaAction以外に普通のHTTP/Sキックをできてほしい…諸々Azureに流したいけどプロキシだけのLambda書くのも嫌な感じ
      • これができると、Azure上で指定容量到達イベントを受け取ってSubscriberをdeactivateするような仕組みをさらっと作れて嬉しい
  • Beam専用モード(Beamのエンドポイント以外への通信を遮断するモード)がほしい
  • BeamのログをS3のバケットにスロッシュしておいてほしい
  • サーバ上で走り続けるプログラムからアクセス元SIMのIMSI検証などをおこなうことを考えると事実上サーバへのID/パスワード保存が必須(トークンを延長し続けていってエラーを吐いたら詰むため)。できればアプリケーションキーなどの権限委譲機構が欲しい
    • 難しいようなら、Operatorの親子関係を作って子側(最悪の場合無効化すればいい)のID/パスワードをサーバへ保存するワークフローを望む

Effective C++読書メモ #35

2015年10月8日木曜日

Item 35: Consider alternatives to virtual functions
前回: Effective C++読書メモ #34
前回はインタフェースの継承と実装の継承をうまく使い分けるという話だった。
今回はvirtual関数の代替策を考えるという話。前回と関連したもの。

Non-Virtual Interface(NVI)を使ったTemplate Methodパターン

virtual関数はほとんどの場合でprivateにすべきという議論があり、それに従うと外部からのアクセス用メソッドをpublicで作成して内部でprivate virtualな実体を呼び出す方法がある。
処理実体の前後に特定の処理(ロギングなど)を挟み込みたい場合に便利。
これをvon-virtual interface(NVI)イディオムと呼び、デザインパターン方面ではテンプレートメソッドと呼ばれるもの。ここでのテンプレートはC++のテンプレートとは関係ないよというのが書かれている。

関数ポインタを使ったStrategyパターン

そもそも処理実体がクラス内に存在する必要がない場合にはNVIイディオムはあまりマッチしない。そういう場合にはコンストラクタに計算用関数のポインタを渡すなどして外部のものを使う方法がある。
この場合は計算ロジックを実行時に選択できるし、同クラスの別インスタンス同士で異なる計算ロジックを利用できる。
一方で計算ロジックが元クラス外にあるということは元クラスのpublic要素にしかアクセスできなくなる問題がある。原則的にこれはクラスのカプセル化をゆるめることで解決するしかない。

tr1::functionを使ったStrategyパターン

さきの関数ポインタによる実装に柔軟性を持たせられるのがtr::functionを使うパターン。
関数の代わりに関数オブジェクトを使ったり、指定型の戻り値の代わりにその型へ変換できる任意の型を使ったり、という便利さを得られる。
[*1] Scott Meyers自身による説明がhttp://www.aristeia.com/EC3E/TR1_info.htmlにある。

クラシックなStrategyパターン

計算用クラスのツリーを作っていき、そのポインタを計算利用側に持つという伝統的なやつ。計算種類を増やしたくなったら計算用クラスを継承して新規作成すればいい。

結果

いろいろな方法が考えられるということはおさえておこうねというのが論旨、という話でおしまい。

すごいHaskell 読書メモ #2

2015年10月7日水曜日

前回: すごいHaskell 読書メモ #1
前回は関数の記述と適用の話だった。if式にはelse節が必須など、いくつかのルールを学んだ。
今回からはデータ構造の話、今回はリスト。

リストの基本操作と性質

まずはリスト。定義の仕方や扱い方はざっくりと他の言語と変わらないように見える。GHCi内での定義にはletを使うとひっそりtipsが書かれてる。
リストの連結は++でおこなう。文字列は文字のリストとして表現されるので、リスト関数は文字列に対して適用できる。
リストの末尾に連結をおこなうのは何度もスキャンが必要となるため遅い。リストの先頭への追加はとても速い(スキャンしないから)。これをおこなう演算子が:cons演算子とも呼ばれる。
ここの例で'h'など文字(Cでいうところのchar相当)指定が出てる。前回の中身でアポストロフィは名前の一部に使えるというのがあったけど、この感じだと先頭には使えない(letter表現とかぶるため)のだろう。
cons演算子(:)で第一引数になるのは連結対象リストの単一要素。++演算子では両方ともリストを渡す。
Haskellでは[1,2,3]は単に1:2:3:[]の糖衣構文と。なるほど。
リストの要素へのアクセスは!!でおこなう。0-origin。リストの端を超えた場所にアクセスすると例外が投げられる。リストの中に更にリストを入れられるけれど、違う型はダメ。
リストの比較は辞書順でおこなわれる。最初に見つかった異なる要素の順序が大小を決定する。空でないリストは常に空リストよりも大きいとみなされる。なので、リストAがリストBのスーパーセットである場合はリストAのほうが大きいとみなされる。ふむ。
その他のリスト操作としてhead/tail/last/initの紹介。結構頻繁に使いそう。
空のリストに対してこれらの操作をすると例外を吐く。length関数で要素数を調べたり、null関数で空か否かを調べたりして空リストへの操作が発生しないように処理すると。
take関数は要素数を指定して取り出す。0を指定して空リスト取り出しができる。試した感じ、take 0 []は問題ない。リスト要素数より多い要素を取り出そうとするとリスト全体が返される。だからtake 3 []は空リストを返すだけで特に問題ない。
maximumminimum関数は想像通りの挙動。elemは要素とリストを受け取って、指定要素がリストに含まれるかを返すもの。中置関数として使うことが多いという説明がされてる。
レンジ指定はまあまあ賢いよという話。[1..20]は自然数を刻んでくれるし、[a..z]は小文字アルファベットを列挙してくれる。
しかし[1.1..20.0]を試してみると
[1.1,2.1,3.1,4.1,5.1,6.1,7.1,8.1,9.1,10.1,11.1,12.1,13.1,14.1,15.1,16.1,17.1,18.1,19.1,20.1]
となったので、まあこんなもんかなと。
2つ目の要素を指定するとその差分を刻みとしてほどよくやってくれると。試しに[1,3..]とすると噂の無限リストがさっくり作れた。割と便利さを感じる。と思ったらすぐ後にそのまま無限リストの話が出てきた。
cycle関数は指定リストを無限にリピートする。おもしろい。repeatは単一要素を受け取ってそれをひたすら繰り返す(yesコマンドぽい)。replicateは指定要素からなる指定長のリストを作るもの。結果だけだとreplicate 3 10take 3(repeat 10)は同じになるけど、内部の処理的にはどっちのほうが効率的なのだろう、というのが気になったりした。
続けてリスト内包表記の話。Pythonなどでお馴染みという感じだけど、あるリストから要素列を取り出して指定の名前に束縛し、加工方法を記載する出力パートに投げ込んで結果リストを作っておしまい。
要素列の取り出しと束縛をおこなうパートにカンマで続けて条件(述語とも呼ぶ)をつけ、元リストからの取り出しをフィルタできると。条件はカンマで区切っていくつも書けるので、複数条件指定のためにわざわざリスト作成を何重にもおこなう必要はない。
複数のリストからの取り出しも構文的には条件と同様なんだけど、利用時をイメージするとイマイチ直感的ではなかった。取り出した要素の全組み合わせが結果リストに反映される(5要素のxと3要素のyなどを取り出すと15要素の結果リストができる)。慣れると便利な局面が多そう。
lengthっぽい関数を独自定義するくだりはゴリ押しすぎて面白かった。まさかの全要素を1に射影してsum*1
リストから取り出したけど使わない値を変数名_に突っ込んで捨てるのはお馴染みのイディオム。
試してみると複数のリストからの取り出しで全部同じ変数へ突っ込むこともできるんだけど、その場合実際に取り出せるのは最後に書いたものらしい。
ghci> [x | x <- [1,2,3], x <- [10,100]]
[10,100,10,100,10,100]
ふむ。どっかに仕様書いてあるだろうからそのうち調べそうなメモ。
リストを含むリストの操作で例示されている[ [ x | x <- xs, even x ] | xs <- xxs ]は慣れるとサクサク読み書きできそうだけど、あまり複雑になりすぎると脳スタックがあふれそうな気もした。外枠から把握していくとルール付ければ破綻はしないか。
と思ったら、入れ子の内包表記は複数行で書いたほうが読みやすいよと注記されていた。誰かのコードを読むなかで慣れよう。
[*1] C#+LINQやRxの文脈でも似たことをやるコードは見かけますが、たとえば極単純な配列長チェックに使う場合は確実に無駄ですね。特定条件でフィルタした結果の件数取得などでは合理的な可能性あります。

おしまい

リストについてはここまで。写経しつつメモを書きながら読み進めたところ、分量的にはあまり進まなかった。各関数の挙動を実際に試しつつなので、まあこんなものかなとも思う。
確実に「おっけー!」という部分がまだほとんどないので、出てきたものを片っ端からメモ取る状態になってるのが辛いところ。この先改善していくと良いけれど、あまり改善しないようなら何かしら方法を考える必要がある。
ふと思い立ってlast (reverse [1..])と叩いてみたけど、結果がかえってくる気配がなかったから^Cで止めた。こういうことは出来ないんだなぁ。

次回

次回はタプルから。

C#でのクロスプラットフォームなコマンドラインツール開発に良いかもと考えながら最近のASP.NET 5事情を調べた

2015年10月6日火曜日

ASP.NET 5?

ASP.NET 5はなかなか意欲的なバージョンです。過去のプロジェクト構成を完全に捨て去っていくスタイルです。
私は去年の暮れ*1に割とがっつり調べたのですが、その後に大きく変わった最近の状況にあまりついていけていませんでした。そういうわけで最近の事情について調べた個人的メモです。
[*1] まだASP.NET 5という名前が決まる前で、ASP.NET vNextと呼ばれていました。

軽量でポータブルな実行環境: DNX(旧 K Runtime)

ASP.NET 5では、過去バージョンにあったWindows縛り・.NETランタイムのバージョン縛りや同一サーバ上への複数バージョンインストールに関する厄介事から解放されることになっています。実行環境自体がポータブルになり、サーバ上へのSxSデプロイも超絶簡単(容量面でもコンパクトかつバージョン競合を避けられる方式になる)になるというのが目玉です。
この、実行環境のポータブル性という面で.NET側でおこなわれている取り組み(.NET Coreプロジェクト)はざっくりと2つに分けられます。
  • 軽量かつクロスプラットフォームなサーバ向けランタイム(CoreCLR)の開発
  • クラスライブラリの整備(CoreFX)
CoreFXでは画面描画系をごっそり無視しています。これらのランタイムとクラスライブラリをサーバ上での実行に適した形でパッケージングし、バージョン切り替えや共存をおこないやすく仕立てたものがDNX(.NET Execution Environment)です*2
私がASP.NET 5(当時のvNext)をちまちまと調べていた頃には.NET Coreプロジェクト自体が発表されておらず、非Windowsのクロスプラットフォーム動作においてはMonoを利用するという流れでした。
.NET Frameworkのソースコード公開(https://github.com/Microsoft/referencesource)と、そこから出発してクロスプラットフォーム(LinuxとOS Xを現状で不安定版サポートしている)の64-bitサーバ用環境として育っていくCoreCLRを見ていると不思議な気持ちでもあります。
DNXでは依然.NETアセンブリの実行やアプリケーションコードのビルドにMonoを利用するランタイムオプションを提供していますが、Mono側のバージョン固定が多少面倒な部分は否めません*3。ASP.NET 5の実サーバ運用においてはMonoが絡むシーンは少なくなっていくのでしょう。
[*2] 2015年の1月頃に、K Runtimeと呼ばれていたものが改称されました。
[*3] まあ、Monoに関しては基本的にどんどん最新版を使っていけばいいのですけれど。

.NET CoreはMonoを殺してしまうの?

そもそも極短期では.NET CoreベースのDNXがマトモに動作しないケースも多いため答えを出すまでもないのですが、私はおおむね中期(-3年)まではNo、と考えています。
非Windows環境でのサーバ系需要を.NET Coreが担っていくことは基本的にMonoとXamarinにとっても良いことと見えます。Monoの太古の需要のひとつは非Windows環境でのASP.NETシリーズ実行だったと記憶していますが、この領域は2015年時点でXamarinのビジネス領域から外れています。現時点のXamarinのビジネス領域は確実にモバイル向けのC#開発環境(可能な範囲でのクロスプラットフォームと共に)で、この領域で同社のリソースを振り向けたいことは山ほどあるはずです。そんななかで(外から見ている分には)Xamarinにとってのサーバ向け領域は「できればそろそろやめたい」エリアと見えます。
もちろん、CoreCLRが進化の果てに他領域(たとえばiOSでのfull-AOTサポート)までを広くカバーするようになり、CoreFXについてもGUIツールキットとの連携または取り込みと各OSの膨大なAPIライブラリに対するまともなバインディングが生えてきたとすると、「ん?これXamarin要らんのでは?」となる世界も想定はできます。この筋が通れば見事なdisruptive innovationとなる可能性がありますね。
しかしそれはつまりMicrosoftが本気でXamarinを殺しにかかっているタイミングで、おそらくは相応の資金を投入してXamarinを買収することによって実現すると考えるのが妥当に見えます。そのへんはきっと先の話なのでよくわかりません。

DNXを構成するコマンド群

機能的には以前調べたタイミングからあまり変わっていません。

dnvmコマンド

RubyのrbenvやNode.jsのnodebrewに相当するコマンドです。ホームディレクトリの下に.dnxというディレクトリを作成し、その下へ各バージョンのランタイムを突っ込んでいくスタイルです。.NET Version Managerの略とされています。
前述のポータブルなランタイムをネット上から拾ってきていい感じにシステム上へ配置し、複数のランタイムを共存させたり利用するバージョンを切り替えたりするために使います。ランタイムのアップデートなどがコマンドひとつで完結するので、これまでの.NET系環境と比較するとかなり楽という感じがします。
今のところ非Windows環境でのデフォルトランタイムはMonoです。
CoreCLRを明示してインストールするためには-r(-runtime)オプションでcoreclrを指定する必要があります。
$ dnvm upgrade -r coreclr

...
Determining latest version
Latest version is 1.0.0-beta7
Downloading dnx-coreclr-darwin-x64.1.0.0-beta7 from https://www.nuget.org/api/v2
Download: https://www.nuget.org/api/v2/package/dnx-coreclr-darwin-x64/1.0.0-beta7
######################################################################## 100.0%
Installing to /Users/muo/.dnx/runtimes/dnx-coreclr-darwin-x64.1.0.0-beta7
Adding /Users/muo/.dnx/runtimes/dnx-coreclr-darwin-x64.1.0.0-beta7/bin to process PATH
Updating alias 'default' to 'dnx-coreclr-darwin-x64.1.0.0-beta7'
ランタイムにMonoを利用するとアプリ起動直後にMonoのインストールパスを探して見つかったものを起動しますが、CoreCLRの場合はdnvmでインストールしたランタイムのディレクトリ以下にあるlibcoreclr.dylib(OS Xの場合)を使ってバイナリを実行していく流れです。
以前はkvmというコマンドでした。kvmって他の用語と被りすぎにも程があるという感じのものだったのですが、dnvmとなりました。長いですね。
他のコマンドも芸なく先頭にdn(.NETの意)と付いて4文字になったのか、と思いきやそんなことはないので安心してください。

dnuコマンド

Node.jsのnpmに相当するパッケージ管理系を担うコマンドです。以前はkpmという名前で、そのまんまでした。
DNXのアプリ定義ファイル(JSON形式)に記述されている依存ライブラリをネット上から拾ってきたりできます。
依存ライブラリ管理のみではなく、buildというサブコマンドを使うとアプリのソースをもとにアセンブリを作成できたり、publishを利用するとアプリをデプロイ用に固めたりということができます。
publishかけてrsync一発で動くような楽な感じの構成はとても良いですね。
packサブコマンドを使うとプロジェクトのNuGetパッケージを作成できます*4。MyGetでの自社向けアプリコード配信とか、なかなか手軽な策になりそうで期待が持てます。
ちなみにdnuは.NET Utilityという、色々と諦めた感じの命名です。
[*4] OS X 10.10 + CoreCLR環境では生成に失敗しますが、同Monoではうまく生成できます。

dnxコマンド

dnvmコマンドで拾ってきた.NET実行環境のエントリポイントとなるのがdnxコマンドです。
ちなみに、Mac(OS X)環境で拾ってきたMono版のdnxコマンドの実体は前述のようにシェルスクリプトですがCoreCLR版は普通にMach-Oのバイナリです。
以前はkreというコマンドでした。

CoreCLR+DNXの印象

Linux上はともかく、Mac(OS X)環境でのx64利用について考えるとDNXと組みにするのはMonoよりもCoreCLRのほうが今後楽しそうです。激しく未完成なことを除けば、現時点でもOS X環境で64-bitランタイムを使いたいシーンではMonoよりも扱いやすいです*6。主に、MonoがOS X向けの通常ダウンロードで64-bit版バイナリを提供していない(自前でビルドはできる)ためですが。
CoreCLR+DNXは、実行環境の取得・バージョン固定・アップデートが楽という特性により、クロスプラットフォームなコマンドラインツール*5を作るための優れた基盤となり得るものです。「クロスプラットフォーム動作するユーティリティをサクサク作りたいけどJavaScript書きたくないな〜〜」という人々の大半はPythonが2と3でゴタついている間にgolangへ行った感がありますが、そこC#でもよくね?と考えていくと夢が広がります。
ひとまず、環境をあまり汚さずに導入できるし、Mac用の導入手順が公式サイトにある(http://docs.asp.net/en/latest/getting-started/installing-on-mac.html)のでMacの方も試してみて「なるほどなるほど〜〜」となってみると楽しいかも、という感想でした。
[*5] あ、グラフィックス(GUI)系を扱う必要がある場合にはMonoを使うという具合です。
[*6] というかCoreCLRはまだきちんと32-bit構成持たないんじゃないかな。JIT実行にRyuJITのみを使ってるのなら。

Effective Objective-C 2.0 読書メモ #20

2015年10月5日月曜日

途中の番号から始まる読書メモシリーズ。
Effective Objective-C 2.0: 52 Specific Ways to Improve Your iOS and OS X Programsは、ObjCを読み書きする際には読んでおいたほうが良い本だと思います。言語の文法を把握してそこそこコードを書けるようになってきたぐらいの人がハマりがちな罠や当該言語流の作法といったものが豊富に書かれていて*2かなりオススメ度が高いです*1
ちなみにObjC関連で私がしっかり読んだ本はこれと@splhack先生のエキスパートObjective-Cプログラミング — iOS/OS Xのメモリ管理とマルチスレッドで、あとは大体オンラインドキュメントと各種公開コードで学んでいった記憶があります。
私はこの本を読み始めてから結構長く、2年少々経ちます。発売日を調べてみると、どうやら刊行後すぐに買って読み始めたようですね。同年の暮れには日本語訳も出ているので、これから読み始めるならこちらのほうが楽だと思います*3。私は、さっと通読した後はObjCを書くタイミングでポイントにより振り返ってたまに読んでいます。
当初はメモを取らずに読んでいて途中からメモを書くようにした都合上、このメモは初回なのに#20からスタートというわけです。実際はもう少し手前のメモも残っているので、気が向いたら整理してみます。
[*1] まあ、他のObjC本をそんなにしっかり読んではいないので、比較ベースで語ることはできないのですけれど。
[*2] 他のEffectiveシリーズと共通するところです。
[*3] Amazonの商品ページを見てみると、翻訳が独特というレビューがついていますね。どの程度なのかは翻訳版を読んでいないのでわかりません。

#20 Prefix Private Method Names

前回は名前付けの話で、またしっかり戻ってきたい話でした。
今回はプライベートメソッド名にプリフィックスをつけろという話です。ObjCには言語的なプライベートメソッドの仕組みがないのでうまく運用でカバーするというのが前提です。
  • Appleのライブラリ群では_をプリフィクスにしているんだけど、それに倣ってはいかんという話が面白かった
    • ObjCの事情として実行時にメソッドが反応できるものを判断するので、不意にでも被ってしまうのは避けたほうが良い
      • コンパイル時に全部確定するわけじゃないという_objc_msg方面の動的解決な話
  • _をプリフィクスとして使ってしまうとクラスの継承タイミングなどで意図せずAppleのメソッドと被る危険性がある
  • なのでp_をプリフィクスにするのが良いという話。
言われてみると確かにそのほうが安全だなー、なるほどなー感が強い回でした。

すごいHaskell 読書メモ #1

2015年10月4日日曜日

前置き

3年半ぐらい前にHaskell公式サイトのオンラインドキュメント(どちらかというと仕様書に近い)からHaskellを学ぶという取り組みをしていたのですが見事に頓挫(http://www.muo.jp/2012/04/haskell_03.html)していました。これはその続きの勉強の話です。

すごいH本

(´・_・`)氏訳の「すごいH本」は1年半ほど前に*1物理本を買い、少しずつ読んでいました。
これは評判に違わぬ良い本で、私から(純粋)関数型プログラミングに対する恐怖感というかつらそう苦しそうという先入観を取り払う役目を担ってくれました。型クラスの説明あたりまでしか読み進んでいない状態でずいぶん時間を開けてしまったのですが、その後にScalaの勉強を始めた時に本の説明がすんなり頭に入ってきたのはこの本のおかげだと思っています。
[*1] 確か、tanakhさんにお会いしてその帰りにAmazonで注文したような憶えがあります。

ない…!

1ヶ月少々ぶりに読もうと思ったんですが、どうも見つからない。
自宅の机のうえで手の届きやすい場所へ置いておいたはずだけど全然見つからない。
家の中をひっくり返して探してみても見つからない。
もしや1ヶ月ぐらい前に数日間アメリカへ行ってきた際の移動時間用に持っていったっきりなのでは、と思い始めました。移動中は結局他のことをやっていて読まなかったため、とても記憶が曖昧です。
(中略)
探すのを諦めて達人出版会の電子版を追加購入しました。本をなくしたのは何年ぶりだろう。

そういうわけで

以前取ったメモの再構成を交えつつ勉強していくメモです。

#1 関数の記述と適用の話

1章を読み始める。いきなりイントロへ戻ってこいと言われる。戻ってみる。ちゃんと読んだ記憶ある。手元のbrew環境にあるGHCを最新版へ念のためアップグレードしておく。
→ghci起動に失敗する、と思ったらbrew環境が全体に古かったので丸ごとアップグレードした。このとき、コマンド実行でコケていたけれど単純にgmpのリンクが切れてるっぽかったのでunlinkしてlinkし直したところうまくいった(brewにありがちなこと)。
/=演算子を2値が等しいかの判定に使っててふぁぁぁと思ったけど、これあれか、≠か。5 /= 55 / 5 == 0で0をC的に真偽判定してFalseという例かと読んでから気付いた。
関数が2引数のときは、関数を``で囲うことで中置関数として呼び出せる。例えば92 `div` 10、なるほど。これよく使われるのかな。
関数の適用は優先度的に明確である限りは括弧無しで引数指定するようなので注意していく*2
[*2] ちなみに、試してみると元々中置関数の - や * を``で囲むと単純にparse errorとなる。
文字列リテラル(というのかまだ知らない)をシングルクォートで囲うと、「TemplateHaskellを使おうとしたのん??」と問われるのでそのうち解消しよう(なんかモジュール要るやつをおせっかいしてくれるのかなGHCi)
  • Haskellでのif式にはelse節が必須
  • すべての関数は何らかの値を返す
    • 他の言語で、コードパスによっては値を返すけど他のコードパスでは返さないような、関数シグニチャと挙動の一致しない定義が許されないのと同様、Haskellのifは必ず値を返す式(文ではない)ゆえ、else必須と
ちょい先でシングルクォート(アポストロフィ)あたりの話が出てきた。Haskellで'は特別な意味を持たず、関数名の一部として有効な文字であると。なるほど。
正格版の関数というフレーズが出てきてなんぞとなったけれど、遅延じゃないと書いてあったのでそういうものだろう。'は他に、ちょい変更した関数の意で名前付けに使うこともあると。慣れないので見づらく感じるけれど、たぶん慣れてる人にとっては見れば分かるような使い分けなのだろう。
だいぶ前にやった覚えのある、Haskellの関数名は大文字で始められないよというところまで来た。引数を取らない関数を定義名前と呼ぶと。
関数呼び出し、関数定義と来て次はリストやタプルの話へ進もうというところで今回は時間切れ。続きは次回。

Effective C++読書メモ #34

Item 34: Differentiate between inheritance of interface and inheritance of implementation
前回: Effective C++読書メモ #33
前回は、複数スコープをまたぐ名前解決ポリシーと、それと付き合っていくためのusingキーワード利用およびforwarding function作成の話だった。
今回は、インタフェースの継承と実装の継承を使い分けるべきという話。基本的にはタイトルの通りで、pure virtual / virtual / 非virtualの使い分けとそれによって得られるものについて。
  • pure virtualな関数宣言による継承クラスでの個別実装強要
    • なおpure virtualな関数宣言に加えてその実装を基底クラス側でおこなうこともできる。継承クラス側で基底クラス名での修飾をおこなわない限り呼び出せないので有用性低いように思える(伏線)
  • pureではないvirtualな関数宣言によるデフォルト実装の提供と、継承クラスでの上書き許容
  • 継承クラスで暗黙的にデフォルト実装を利用したらまずいケース
    • pure virtualな関数宣言とprotectedな別名のデフォルト実装を提供することで、継承クラス側にて明示的に親の提供するデフォルト実装を指定できる
    • こうすると名前空間のなかにごちゃごちゃと類似機能のメソッドを増やすことになるのが嫌という考えもある
      • その際は、前述のpure virtualな関数宣言+実装を基底クラス側でおこなっておき、継承クラス側では明示的にその実装を呼び出す策が使える
終盤でざっくりとこれらの使い分けについて記載があった。
全メンバーが非virtualなのはヤバそうなクラス設計の兆候。
全メンバーがvirtualなのも同様。これは良い設計である場合もあるけど、単純にクラス設計者の考慮漏れという可能性もあるため、という締め。

Effective C++読書メモ #33

2015年10月3日土曜日

Item 33: Avoid hiding inherited names
前回: Effective C++読書メモ #32
長くメモを書いていなかったので続き。前回はパブリック継承の話だった。今回は、継承した名前を隠すのは避ける(あるいはその状況とうまく付き合っていく)という話。
継承の問題というよりはスコープの問題。内側のスコープで名前解決に成功した場合は外側での解決は一切おこなわないため、内側と外側で型が違っていようが何も考慮されない。
ローカルスコープでの名前解決、次に外側としてクラス、次に基底クラスを調べたところで解決できたらそれを使うと。なお、ここで見つからない場合はローカル側の所属する名前空間を見て、最後にはグローバル名前空間を見にいく。
このルールはメソッドについても適用されるし、メソッドの場合はシグニチャベースではなくてメソッド名での名前解決がおこなわれるために継承クラスで基底クラスと同名別パラメータのメソッドを作っても基底クラスのメソッドが隠される結果になる。
継承クラス側で基底クラス側と同名の定義をおこなうことで隠れるものを明示的に継承クラス側に見えるようにするためには
using Base::foo;
の構文での取り込みが必要。
public継承の場合はこれでいいけれど、private継承が絡んでくると少々事情が異なる。private継承をおこなったクラス側で特定のオーバーロードのみを継承したい際には、forwarding function(プロキシ的なもの)を書くことになる。
古のコンパイラがusingを正しくサポートしていない際のための回避策としてもforwarding functionの導入は有効と書かれているけれど、さすがにその方面のコンパイラを触る気持ちは無いので見なかったことにする。
テンプレートが絡むと事情が変わるということで、そのへんはまた今度(#43かな)。

Azure Data FactoryのGA (Azure ML blogメモ)

Azure ML(Machine Learning)は、クラウドで動作する機械学習の仕組みです。MicrosoftのAzureサービス群のなかでも他の大手クラウドサービスになかなか無いものを提供している、個人的にかなり好きなサービスです(私自身は機械学習クラスタではありません)。
MicrosoftのTechNetにはMachine Learning Blogというのがあり、Azure MLやその他Microsoft関連の機械学習系トピック(新サービスの紹介など)が週に2本程度の頻度で書かれています。
これは割と読んでいて面白いのでちょいちょい読んでいるのですが、すぐに忘れてしまってもったいないので振り返り用に簡単なメモを残してみます。

Azure Data FactoryのGA

メモ対象記事: Announcing the General Availability of Azure Data Factory(2015/08/06)

本文メモ

  • 著者: Joseph Sirosh(Information ManagementとMachine LearningのVP)
  • Azure Data Factory(ADF)がGAになったよという話
  • ADFはCortana Analytics Suiteのコアコンポーネントのひとつ
    • データの移動と変形を扱い、オーケストレーションと自動化をおこなうデータ統合サービス
    • Azure内の各種サービスのなかでもかなり使われてる
    • データ処理に関わるいろんなサービスをつなぎあわせて自動処理するための仲介役となるサービス
    • 個別のリソース管理を頑張らなくてもクラウドで勝手にやってくれるというのが嬉しいところ
  • すでにRockwellやAlaska Airlines、Millimanで使っている
  • Cortana Analytics Suiteの利用料金や提供時期などの詳細は2015年の秋に発表する予定
  • ADFはhttp://www.azure.com/adfからアクセスできる

感想

  • 1ヶ月ちょい前にAlaska Airlinesを使った時にはさほどエンタメシステムがパーソナライズされているようには思わなかったけれど、そりゃ初利用で最適化されてたら引くし。頻繁に飛んでる人用の最適化なんだろう
  • オンプレとクラウドのデータ処理系をつなぎあわせて使うのに力を発揮するイメージ。MSは本当にこの切り口をAzureの展開において大切にしてる
  • データをじゃばじゃば流し続ける系のインフラとミドルウェアをスケーラブルさ保ちつつメンテしつづけるのはお高いし大変だよねという話
  • Cortana Analytics Suiteも楽しみ