読者です 読者をやめる 読者になる 読者になる

しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

シアトル滞在中の食生活と UberEATS を使ってみた話

日常

シアトルだけじゃなくてベルビューも含みます。今回の MVP Global Summit では致命的に食事が合わなくて辛かったので、何とか日本食や食べられそうなものを探す日々でした。

来年また参加するかもしれない自分のためにもメモとして残しておきます。

Hokkaido Ramen Santouka

https://www.yelp.co.jp/biz/hokkaido-ramen-santouka-bellevue

f:id:shiba-yan:20161108202229j:plain

日本で山頭火に行ったことなかったですが、日本のラーメンだったので安心感が半端なかったです。

ただしラーメン 1 杯が確か 12 ドルぐらいしました。

13 Coins

https://www.yelp.co.jp/biz/13-coins-restaurant-bellevue

f:id:shiba-yan:20161110205516j:plain

普通のステーキを頼んだはずなのに、付け合わせのパスタの方が多かったので、アメリカ人は本気で頭がおかしいと確認した瞬間でした。しかもパスタには味がついてない。

Din Tai Fung

https://www.yelp.co.jp/biz/din-tai-fung-bellevue

f:id:shiba-yan:20161112112428j:plain

台湾と日本の両方で行ったことがある店ですが、味が変わってなかったので安心感がありました。朝と昼はフルーツとコーラのみという生活をしていたので、やっと食事に関して人権を得ることが出来ました。

Karaage Setsuna

https://www.yelp.co.jp/biz/karaage-setsuna-seattle

f:id:shiba-yan:20161116124635j:plain

シアトルダウンタウンに移動してからはクラムチャウダーを 2 日連続で食べていましたが、一瞬で飽きてしまったのでネットで日本食を探しまくって見つけた店です。

日本人のオーナーがやっている店なので安心感が半端ないです。量が多いので注意。

Shiro's Sushi

https://www.yelp.co.jp/biz/shiros-seattle

f:id:shiba-yan:20161116181045j:plain

f:id:shiba-yan:20161116182647j:plain

絶対に間違いのない寿司屋としてダウンタウンでは鉄板の店です。カウンターで食べると無限寿司になるので、油断してると一瞬で 100 ドル超えるので注意したいですね。

あったかいお茶が飲める店としても貴重かもしれません。

UberEATS を使ってみた

ホテルから外に出たくない日があったので、初めて UberEATS を使ってみました。店舗数は結構多かったですが、食べれそうなものを絞り込むと選択が難しかったです。

f:id:shiba-yan:20161203233534p:plain:w450

アプリの使い方は簡単で、日本と全く同じように使えるので Uber 最高という感じです。

いろいろと諦めて Santouka で注文をしてみました。ラーメンは電子レンジがあれば注文できるみたいですが、なかったので鮭いくらご飯と唐揚げを選びました。

f:id:shiba-yan:20161203233557p:plain:w450

配達料は 3 ドルぐらいでした。Uber に乗って食べに行くよりも安いです。

注文が確定すると状況を確認できるようになります。日本のピザ屋によくあるやつです。

f:id:shiba-yan:20161203233618p:plain:w450

配達予想時間が表示されますが、思ったよりも前倒しになったので目安として考えておけば良さそうです。

Uber によって配達が開始されると地図でトラッキングが出来ます。

f:id:shiba-yan:20161203233633p:plain:w450

ドライバーの名前と車のナンバーが表示されるので、あとは受け取りやすそうな場所で待って受け取ります。

陽気な感じのドライバーさんから受け取って、実際に届いたものはこんな感じです。

f:id:shiba-yan:20161111193555j:plain

30 分かからないぐらいで届いたので、宅配サービスとしてはかなり優秀だと思いました。

日本でもエリアが広がってくれるのを期待してます。

Windows Containers の挙動について気になった部分だけ調べてみた

Windows

タイトルの通り、個人的に Windows Containers を弄ってみて、気になった部分だけを少し調べました。調べ始めるきっかけは Cloud Services で Docker デプロイしたいってことだった気がします。

結局それはダメだったの、Azure Container Service の Windows 対応に期待してます。

Windows Server Containers は C: に Windows が必要

この制約は知りませんでした。Twitter でぶちぞう RD に教えてもらいました。

カーネルをホストと共有する関係上、決め打ちにならざるを得なかったのかしれません。当たり前という感じですが、Hyper-V Containers の場合はこの影響を受けません。

Windows Server Container hosts must have Windows installed to c:. This restriction does not apply if only Hyper-V Containers will be deployed.

Windows Container Requirements

Azure VM などに Windows Server 2016 をデプロイすると、デフォルトで C: にインストールされるので問題ないですが、この制約の影響を全力で受けそうなのが Cloud Services ですね。

Cloud Services では Windows が D: にインストールされているので、そこに依存している App Service の Windows Containers 対応は難しそうです。

コンテナのカルチャとロケール

既にパブリッククラウド向けにアプリケーションを開発している場合には影響しないと思いますが、地味に気になるのがシステムのカルチャとロケールです。それぞれで簡単に確認しておきました。

まずは Windows Server Containers を使って確認します。いつも通り docker run を使います。

docker run -it microsoft/windowsservercore powershell

f:id:shiba-yan:20161203004030p:plain

Windows Server Containers を使って起動したコンテナの場合は、ロケールがホストと同じになるようです。つまり、開発環境では Japanese だけども、クラウドに持っていくと English に変わるということです。

次に Hyper-V Containers を使って確認します。--isolation=hyperv を付けるだけの違いです。

docker run -it --isolation=hyperv microsoft/windowsservercore powershell

f:id:shiba-yan:20161203004332p:plain

Hyper-V Containers を使って起動したコンテナでは、ロケールはホストとは異なり英語になりました。名前の通り Hyper-V を使っているだけあって、通常の VM に近い挙動ですね。

ロケールは変更が出来ないようなので、アプリケーション側で依存しないように作る必要があります。

コンテナのタイムゾーン

いい加減に UTC と JST で失敗する人は少なくなってると思いますが、一応確認しておきます。一般的なクラウドサービスのタイムゾーンは UTC となっているので、依存するのはそもそも NG です。

f:id:shiba-yan:20161203010240p:plain

f:id:shiba-yan:20161203010350p:plain

文字化けしてますが Windows Server Containers と Hyper-V Containers 共にホストのタイムゾーンが反映されていました。開発環境では問題なくても、本番に持っていくと失敗するタイプなので注意しましょう。

要するに Azure App Service などの、ロケールやタイムゾーンが変更できない系 PaaS を使っているアプリケーションは、あっさりと Windows Containers でも動作しそうです。

AWS Lambda で C# を使って SendGrid の Event Webhook を受信する処理を書いた

AWS SendGrid

AWS Lambda が C# に対応したと聞いたので、Visual Studio を使って試してみることにします。

そして今日は SendGrid Advent Calendar の担当日でもあるので、ありがちですが Event Webhook を受け取る処理を書いてみます。まずは Lambda の C# 対応については公式ブログを。

Announcing C# Support for AWS Lambda | AWS Compute Blog

AWS Toolkit for Visual Studio がアップデートされたらしいので、Lambda Function は Visual Studio を使って作成していくことにします。

インストールするとプロジェクトテンプレートが追加されるのでわかりやすいですね。

f:id:shiba-yan:20161202142854p:plain

Serverless Application も気になりますが、とりあえず AWS Lambda Project を選びます。

作成されたプロジェクトの構造はシンプルです。普通の .NET Core コンソールアプリケーションをデプロイする形になるみたいです。この辺りは Azure Functions とは異なりますね。

f:id:shiba-yan:20161202143240p:plain

Lambda Project が用意できたので、実際に Event Webhook を処理するためのコードを書いていきます。Event Webhook から送信されてくる JSON の構造はドキュメントの通りです。

Event Webhook - SendGrid Documentation | SendGrid

JSON はクラスにマッピングしますが、LambdaSerializer が input というパラメータに対してデシリアライズを自動で行ってくれるようなので、かなりすっきりと書くことが出来ました。

本来なら DynamoDB などに入れると思いますが、今回はログにデータを書き出すだけにしておきました。

using Amazon.Lambda.Core;

using Newtonsoft.Json;

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]

namespace AWSLambda1
{
    public class Function
    {
        public string FunctionHandler(EventWebhookData[] input, ILambdaContext context)
        {
            foreach (var data in input)
            {
                context.Logger.LogLine($"{data.Email} - {data.Event}");
            }

            return "OK";
        }
    }
    
    public class EventWebhookData
    {
        [JsonProperty("sg_message_id")]
        public string SgMessageId { get; set; }

        [JsonProperty("email")]
        public string Email { get; set; }

        [JsonProperty("timestamp")]
        public long Timestamp { get; set; }

        [JsonProperty("smtpid")]
        public string SmtpId { get; set; }

        [JsonProperty("event")]
        public string Event { get; set; }
    }
}

JsonSerializer は JSON.NET を使っているので、プロパティに別名を付けることが出来ます。

これで Lambda Function の実装は終わったので AWS にデプロイします。事前に認証情報の作成が必要ですが、Web アプリケーションなどと同様にプロジェクト右クリックメニューからデプロイが行えます。

f:id:shiba-yan:20161202143504p:plain

ダイアログでは Lambda Function の名前や .NET Core のランタイム設定などを行います。作成時にエントリポイント周りは自動的に設定されるので、そんなに手間はかかりません。

これでデプロイを実行すると Lambda リソースが作成されます。

f:id:shiba-yan:20161202144221p:plain

Webhook として Lambda を実行するには API Gateway を使う必要がありますが、この辺りは本質的な部分ではないので省略します。適当に POST でリソースを追加するだけで問題ないです。

API Gateway を作成すれば、あとは SendGrid の設定から作成した URL を設定するだけです。

f:id:shiba-yan:20161202163409p:plain

この設定画面からはテスト送信が行えるようになっているので、試しに実行しておきます。少しタイムラグはありますが、数秒後には送信が行われるはずです。

Lambda の実行ログを CloudWatch から確認します。

f:id:shiba-yan:20161202163239p:plain

テストデータを正しくパースしてログに書き出していることが確認できました。気になる実行時間は初回はやはり少し時間がかかりましたが、2 回目以降はかなり高速に処理されていました。

Azure Functions と AWS Lambda の両方で C# が使えるようになりましたが、Azure Functions は .NET Framework 4.6.2 なのに対して、AWS Lambda は .NET Core 1.0 と違いがあります。

利用できるライブラリに差が出てくるので、少し注意したいです。