先週、やっとアプリを App Store にサブミットしました。ついでに、バックエンドの Web Api も Refactoring して、もっと速くなりました。その改善の一つとしては、HttpClient を使って、他の Endpoint からデータを取得する処理を全て async にしました。たとえば、三つの Http Call をするところ、await Task.WhenAll(<TaskList>) を使って、Concurrency になりました。三つ Call を並べたら、500 ms * 3 の処理を、500ms ちょっとでできます。
ただ、一つだけ、最初は Task.Run() を使って、そのタスクを await しようとのコードを発見しました。それは間違いです。なぜなら、Task.Run は Thread pool から一つのスレッドを申請して、そのタスクを実行しようとします。本来、現在のスレッドを await すると、もっと別のリクエスト処理できるのに、逆にもう一つのスレッドを使ったので、async の意味がなくなります。タスクを await すると、IO の処理は実行している間、CPU Heavey の処理が実行できますし、今のスレッドを一時的に手放して、他のリクエストも処理できます。遅い IO 処理が終わったら、また元の Call Context から処理を Resume して、本来のタスクを完成します。
一つの Best Practice としては、async を使うと、Top-Down で全てを async にしたほうがいいです。そうしないと、デッドロックが発生するかもしれない。参考として下記のブログが詳しく説明されています。
async を block しないで
また、ASP.NET で await void を関数をできるだけ使わないでください。こちらは実際問題が起こされて、一つの AWS Box が応答しなくなりました。原因はまだ調査していますが、await void は結構危険です。
それでは。
Code
2015年9月12日土曜日
2015年8月22日土曜日
Event Handler を DOM 要素に Bind する時のテクニック
先週、ついリリースしました。今はアプリの App Store と Play Store の承認を待っています。たぶん大丈夫でしょう。最後のバグは jQuery 関係の Event Handler の Bind です。ある <a> tag のクリックに ScrollTo の jQuery Animation を呼びたかったが、アニメーションが実行されなくて、普通に飛んで行きました。
詳細を調べてみたら、本来すでに Click に Handler を Bind して、 ScrollTo を呼び出しましたけど、チームの新人さんがそれが知らなくて、別の関数で実現しました。しかも stop(true, true) で前のアニメーションを全てキャンセルして、自分のアニメーションを実行していました。考え方としては問題がありません。ただ、stop() の第二の引数 jumpEnd です。true を渡すと、前のアニーメーションの最後までいきなり実行します。これがバグのルートです。ただ、stop(true) を呼ぶと、普通に正しく実行できました。
最初は大騒ぎでしたが、問題はどこにも存在するイベントの Bind です。もし、全ての Bind を各ページに譲って、固定の箇所にしたら、たぶん新人さんでも気づくでしょう。たとえば、jQuery.ready() の中、ページの js ファイルに定義するとか。もし複数のページが同じコードが使うなら、main.js の固定場所に 置くとか。
もう一つはアニメーションの使い方です。むやみに全てのアニメーションをキャンセルするのがどうかと思います。気軽に全てを止めったり、キャンセルしたりすると、思わぬバグに繋がります。
幸い新人さんがすぐ私に聞いたので、コードはよく知ってるので、すぐ直しました。今後、どこで何をするかを一応ドキュメントにも残したいと思います。
後、Back End のデータベース Oracle が AWS で他のチームと衝突したので、SQL Server に乗り換えました。後日また詳細を。
それでは。
詳細を調べてみたら、本来すでに Click に Handler を Bind して、 ScrollTo を呼び出しましたけど、チームの新人さんがそれが知らなくて、別の関数で実現しました。しかも stop(true, true) で前のアニメーションを全てキャンセルして、自分のアニメーションを実行していました。考え方としては問題がありません。ただ、stop() の第二の引数 jumpEnd です。true を渡すと、前のアニーメーションの最後までいきなり実行します。これがバグのルートです。ただ、stop(true) を呼ぶと、普通に正しく実行できました。
最初は大騒ぎでしたが、問題はどこにも存在するイベントの Bind です。もし、全ての Bind を各ページに譲って、固定の箇所にしたら、たぶん新人さんでも気づくでしょう。たとえば、jQuery.ready() の中、ページの js ファイルに定義するとか。もし複数のページが同じコードが使うなら、main.js の固定場所に 置くとか。
もう一つはアニメーションの使い方です。むやみに全てのアニメーションをキャンセルするのがどうかと思います。気軽に全てを止めったり、キャンセルしたりすると、思わぬバグに繋がります。
幸い新人さんがすぐ私に聞いたので、コードはよく知ってるので、すぐ直しました。今後、どこで何をするかを一応ドキュメントにも残したいと思います。
後、Back End のデータベース Oracle が AWS で他のチームと衝突したので、SQL Server に乗り換えました。後日また詳細を。
それでは。
2015年8月3日月曜日
セキュリティ:クッキー
つい先週、最後のセキュリテイチェック、パフォーマンステスト、Non-Functional テストが終わって、開発した Web API が live になりました。そのチェックの中に、クッキーの設定について、指摘がありました。ASP.NET を使ってるので、web.config に下記の設定追加しろうと。
<system.web>
<httpcookies httpOnlyCookies="true" requireSSL="true" />
</system.web>
今回の Web API では、セッションは OAuth を使っていますし、各 Endpoint は完全に Stateless で、クッキーとか使っていません。ただ、念のため、上記の追加しました。
クッキー値の設定では、四つのフラグが あって、この中の二つは httponly と secure です。
httponly を設定すると、JavaScript からそのクッキーの値が見えなくなります。ただ、クッキーは browser の 各 request には存在します。こうすることで、 document.cookie が .ASPXAUTH などのセッション Id が見えなくなるので、ajax でのセッションハイジャックはある程度防げます。
サーバーから Set-cookie の値が以下になります。
Set-cookie: sessionId=abcdef; path=/; HttpOnly
もう一つの requireSSL フラグは secure フラグをクッキー値に設定します。つまり、scheme は Https の場合のみ、クッキーをサーバー側に送信します。http でサイトを見る場合、または http で image などを要求する場合では、そのクッキーが見えません。
サーバーから response での Set-cookie は以下になります。
Set-cookie: sessionId=abcdef; path=/; Secure
こうすることで、ある程度クッキーが保護されます。別にクッキーが使わなくても、フラグを true に設定したほうがいいでしょう。
覚えておこう。
<system.web>
<httpcookies httpOnlyCookies="true" requireSSL="true" />
</system.web>
今回の Web API では、セッションは OAuth を使っていますし、各 Endpoint は完全に Stateless で、クッキーとか使っていません。ただ、念のため、上記の追加しました。
クッキー値の設定では、四つのフラグが あって、この中の二つは httponly と secure です。
httponly を設定すると、JavaScript からそのクッキーの値が見えなくなります。ただ、クッキーは browser の 各 request には存在します。こうすることで、 document.cookie が .ASPXAUTH などのセッション Id が見えなくなるので、ajax でのセッションハイジャックはある程度防げます。
サーバーから Set-cookie の値が以下になります。
Set-cookie: sessionId=abcdef; path=/; HttpOnly
もう一つの requireSSL フラグは secure フラグをクッキー値に設定します。つまり、scheme は Https の場合のみ、クッキーをサーバー側に送信します。http でサイトを見る場合、または http で image などを要求する場合では、そのクッキーが見えません。
サーバーから response での Set-cookie は以下になります。
Set-cookie: sessionId=abcdef; path=/; Secure
こうすることで、ある程度クッキーが保護されます。別にクッキーが使わなくても、フラグを true に設定したほうがいいでしょう。
覚えておこう。
2015年7月30日木曜日
React.js と AngularJS、どっちがいい?
追加:下記は React.js 実際使う前の書き込みです。こちらも:
React.js Vs AngularJS、どっちがいい その2
React.js Vs AngularJS、どっちがいい その3 - React.js 速い!
最近、隣のチームのプロジェクトでは AngularJS がヘビーだから、 React.js にしたと聞きました。最初、そのチームは AngularJS を使って、Demo を作りました。モバイルでテストすると、何かウェブサイトがすこし応答が遅いと思ったそうです。でも、それは AngularJS の問題ではないと思います。実際向こうのデモサイトを見てみたら、$timeout() がいっぱいあったりして、Directive もいっぱい作って、本来計算が終わったら、$apply を使うべきところを全部 $timeout を使ったりしていました。Angular の使い方としては間違ってると思います。Dirty Check はただ Model 変化をチェックする方法の一つです。Getter Setter の中にいろいろ判断するより、Dirty Check は理解しやすいし、重い処理は Framework に譲れたと思われています。
まぁ、そのチームが React.js に乗り換えったら、Flux を使って、プログラム全体の構造は3年前 Backbone.js を使った時とほぼ同じになりました。実際デモサイトと比べると、それほど速いと思われてないし、勉強とか、Cross Browser の対応とか、またいろいろ苦労したそうです。最初デモサイトがモバイルでは重いと思われたことは 300ms Click との関係もなくはないと思います。
しかも、React.js を使ったら、プログラム全体がわかりづらくなりました。Flux の Dispatcher を理解しない限り、どこで、何が更新されたかさっぱりわかりません。。。
逆に AngularJS だったら、Controller, Service とかすぐ見つかるし、Back end の開発者もある程度見ればわかります。
多分、区別はそこだと思います。React.js は Framework というより、ライブラリだと思います。つまり、アプリとみなすには、Flux などイベント Dispatcher、Model などをまた作らなければなりません。それを考えてみると、Polymer のほうが使い易いと思いますし、速度的には React.js の Virtual DOM より、それほど遅くないと思います、どうせメモリ上の比べだから、Dirty Check でも。
将来 AngularJS 2.0 をかなり期待できると思います。Polymer とのシームレスとか、遅延ロードとか、Framework としてはかなりいいフィーチャーになります。
まぁ、まだ React.js を詳しくみてないから、こう思ってますが、実際 React.js を View にして、AngularJS の Framework に組み込んだら、面白いかもしれません。
今のプロジェクト一段落したら、また React.js を使ってみて、AngularJS と比べたいと思います。
それでは。今現在の考えで。
React.js Vs AngularJS、どっちがいい その2
React.js Vs AngularJS、どっちがいい その3 - React.js 速い!
最近、隣のチームのプロジェクトでは AngularJS がヘビーだから、 React.js にしたと聞きました。最初、そのチームは AngularJS を使って、Demo を作りました。モバイルでテストすると、何かウェブサイトがすこし応答が遅いと思ったそうです。でも、それは AngularJS の問題ではないと思います。実際向こうのデモサイトを見てみたら、$timeout() がいっぱいあったりして、Directive もいっぱい作って、本来計算が終わったら、$apply を使うべきところを全部 $timeout を使ったりしていました。Angular の使い方としては間違ってると思います。Dirty Check はただ Model 変化をチェックする方法の一つです。Getter Setter の中にいろいろ判断するより、Dirty Check は理解しやすいし、重い処理は Framework に譲れたと思われています。
まぁ、そのチームが React.js に乗り換えったら、Flux を使って、プログラム全体の構造は3年前 Backbone.js を使った時とほぼ同じになりました。実際デモサイトと比べると、それほど速いと思われてないし、勉強とか、Cross Browser の対応とか、またいろいろ苦労したそうです。最初デモサイトがモバイルでは重いと思われたことは 300ms Click との関係もなくはないと思います。
しかも、React.js を使ったら、プログラム全体がわかりづらくなりました。Flux の Dispatcher を理解しない限り、どこで、何が更新されたかさっぱりわかりません。。。
逆に AngularJS だったら、Controller, Service とかすぐ見つかるし、Back end の開発者もある程度見ればわかります。
多分、区別はそこだと思います。React.js は Framework というより、ライブラリだと思います。つまり、アプリとみなすには、Flux などイベント Dispatcher、Model などをまた作らなければなりません。それを考えてみると、Polymer のほうが使い易いと思いますし、速度的には React.js の Virtual DOM より、それほど遅くないと思います、どうせメモリ上の比べだから、Dirty Check でも。
将来 AngularJS 2.0 をかなり期待できると思います。Polymer とのシームレスとか、遅延ロードとか、Framework としてはかなりいいフィーチャーになります。
まぁ、まだ React.js を詳しくみてないから、こう思ってますが、実際 React.js を View にして、AngularJS の Framework に組み込んだら、面白いかもしれません。
今のプロジェクト一段落したら、また React.js を使ってみて、AngularJS と比べたいと思います。
それでは。今現在の考えで。
2015年7月5日日曜日
Youtube ビデオを responsive にする方法
先週、モバイルの WebView を使って、文章を表示する機能をアプリに追加されました。エディターから一つの要求は youtube のビデオを表示したいです。基本的に文章は Responsive をしているので、コンテンツは問題なく各種のモバイルスクリーンサイズが適応できますが、youtube ビデオは iframe の中にあるし、youtube の JavaScript ライブラリで作成されますので、responsive にするには with と height を 16:9 で固定する必要があります。ただ、iframe のサイズを変更するには JavaScript 以外だったら、すこし難しいです。特に、JavaScript を web page に使いたくない時があります。
調べて見たら、css- trick からcss だけで youtube ビデオを responsive にする方法がありました。まず、ifarme にラッパーに置きます。html は以下の通り:
<div class="video-wrapper">
<iframe width="480" height="270" src="http://www.youtube.com/embed/{youtube-video-id}?rel=0&hd=1" frameborder="0" allowfullscreen></iframe>
</div>
そのあと、css:
.video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-top: 25px;
height: 0;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
調べて見たら、css- trick からcss だけで youtube ビデオを responsive にする方法がありました。まず、ifarme にラッパーに置きます。html は以下の通り:
<div class="video-wrapper">
<iframe width="480" height="270" src="http://www.youtube.com/embed/{youtube-video-id}?rel=0&hd=1" frameborder="0" allowfullscreen></iframe>
</div>
そのあと、css:
.video-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-top: 25px;
height: 0;
}
.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
ここのトリックは padding-bottom です。パーセンテージにすると、width の長さになります。ここ 56.25% を設定すると、width とのアスペクト比は 16:9 になります。
次、iframe を 100%, 100%, position を absolute に設定したら、親要素の中にフル表示されます。
参考にしたページは
css でいろいろできるなと。例えば、これ:
それでは。
2015年6月28日日曜日
RESTful API データが見つからない場合の処理
今 RESTful API をベースに iOS や Android のアプリにデータを提供するシステムを作っています。基本的になんでも json を返します。それで、HTTP メッソードを使ったり、 HTTP Response コードを使って、フロントエンドとやりとりをしています。
HTTP メッソードの方は特に決まってるので、Read (Get), Create (Post), Update (Put または Patch), Delete (Delete)特に問題が起きてませんでした。まぁ、たまに Read を Post メッソードを使う API もありますけど。(GET には HTTP body がルールとして使わないので、複雑なオブジェクトをバックエンドに送る時、例えば、複数検索条件とか、Post も使ったりします。)
戻り値は HTTP Response コードなので、200 OK, 201 Created, 202 Accepted とかは理解しやすいです:Get (200 OK), Post (201 Created), Put/Patch (200 OK), Delete (200 OK) 一見ですぐわかりますので、唯一考えるべきコードは 404 Not Found ですね。
私見ですが、データが見つかってない場合、404 ではなくで、空の データ body を返すべきです。なぜなら、404 には url が存在しない場合もサーバーから返すので、意味が紛れ易いです。
一般的に JSON を扱うライブラリでは空の配列や []、オブジェクト {} など空のデータに deserialize しますが、空の body の場合、null に deserialize します。それで、Front End が null かどうかチェックすればいいのです。
404 が返す場合、これは HTTP Request がエラーになったと同じ意味なので、違うルートになります。だからコードには
if (response.StatusCode == 404) {...}
みたいなコードがあっちこっち出てくるかもしれません。そうすると、全体的にエラーの扱いが難しくなります。
データはデータなので、見つからない場合は、200 OK, null body を返したら Front end もすぐわかります。
もう一つは Java, Objective-C, C# などは全て Strongly typed 言語なので、JSON を deserialize する場合、一般的に一つの Class を定義しますが、データの角度から見ると、処理に合わせて、たまに Dictionary<string, object> にしたほうがやりやすい場合もあります。
例えば、JSON オブジェクトの中に、どのプロパティの値が null かをチェックする場合、Reflection を使うより、直接 Key-Value pair にしたらい、Iteration メッソードを使えば、速いし、その後の処理も楽になるはずです。
それでは。ここまで。
HTTP メッソードの方は特に決まってるので、Read (Get), Create (Post), Update (Put または Patch), Delete (Delete)特に問題が起きてませんでした。まぁ、たまに Read を Post メッソードを使う API もありますけど。(GET には HTTP body がルールとして使わないので、複雑なオブジェクトをバックエンドに送る時、例えば、複数検索条件とか、Post も使ったりします。)
戻り値は HTTP Response コードなので、200 OK, 201 Created, 202 Accepted とかは理解しやすいです:Get (200 OK), Post (201 Created), Put/Patch (200 OK), Delete (200 OK) 一見ですぐわかりますので、唯一考えるべきコードは 404 Not Found ですね。
私見ですが、データが見つかってない場合、404 ではなくで、空の データ body を返すべきです。なぜなら、404 には url が存在しない場合もサーバーから返すので、意味が紛れ易いです。
一般的に JSON を扱うライブラリでは空の配列や []、オブジェクト {} など空のデータに deserialize しますが、空の body の場合、null に deserialize します。それで、Front End が null かどうかチェックすればいいのです。
404 が返す場合、これは HTTP Request がエラーになったと同じ意味なので、違うルートになります。だからコードには
if (response.StatusCode == 404) {...}
みたいなコードがあっちこっち出てくるかもしれません。そうすると、全体的にエラーの扱いが難しくなります。
データはデータなので、見つからない場合は、200 OK, null body を返したら Front end もすぐわかります。
もう一つは Java, Objective-C, C# などは全て Strongly typed 言語なので、JSON を deserialize する場合、一般的に一つの Class を定義しますが、データの角度から見ると、処理に合わせて、たまに Dictionary<string, object> にしたほうがやりやすい場合もあります。
例えば、JSON オブジェクトの中に、どのプロパティの値が null かをチェックする場合、Reflection を使うより、直接 Key-Value pair にしたらい、Iteration メッソードを使えば、速いし、その後の処理も楽になるはずです。
それでは。ここまで。
2015年6月14日日曜日
祝 Polymer が 1.0 になりました
先日、つい Polymer JS が Product Ready (1.0) になりました。
https://www.polymer-project.org/1.0/
これは Web の Future と言って、なかり使いやすいです。
また、将来 AngularJS 2.0 ではシムレスに Polymer の要素を Directive と使えることができます。
PS: React.js はどう見ても、FaceBook など表示に重点をおいたサイトでは使いやすいかもしれませんが、Interactive の重いアプリではやはり AngularJS のほうがいいと思います。
後日また。
https://www.polymer-project.org/1.0/
これは Web の Future と言って、なかり使いやすいです。
また、将来 AngularJS 2.0 ではシムレスに Polymer の要素を Directive と使えることができます。
PS: React.js はどう見ても、FaceBook など表示に重点をおいたサイトでは使いやすいかもしれませんが、Interactive の重いアプリではやはり AngularJS のほうがいいと思います。
後日また。
登録:
投稿 (Atom)