Azureはじめました

Windows Azureで業務システムを組んでみる日記

SQLServerのテーブル値関数(Table Valued Function:TVF)のパフォーマンスが突然悪化する件

やめて!

障害は突然に

安定稼働してたサービスのユーザーから一部の機能が急に遅くなったとクレームが。
試してみると確かに遅い。
Webサービス側を再起動や再デプロイしてみても状況は変わらず。
更にローカルの開発環境からSQLAzureに接続しても同様の現象が出た。

( ゚Д゚) あぁこれSQLAzure側や…

続きを読む

RFC違反のEmailAddressを許容するEmailAddressAttributeを作る

.Netが標準で用意しているEmailAddressAttribute(System.ComponentModel.DataAnnotations)で本来は必要十分なんだが、Docomoauの過去の遺産であるRFC違反アドレスは今もまだ使用されており、ひょんなことからコイツが現れてエラーを巻き起こす。

NTTドコモが新規に取得できるiモードメールにおけるメールアドレスをRFC準拠に変更したとのことです。これまでNTTドコモiモードメールおよびauEZWebにおけるメールアドレスがRFCに準拠していない「.(ピリオド)」の連続利用などができていましたが,iモードメールにおける新規取得分についてはそれらを変更して,RFC準拠としたということです。とここまで書いたけど,mopera Uも大丈夫ですよね?と思ったけど大丈夫っぽいのかな。@の前の.の話がないけど。auも注意が書いてあるから後追いするかな。過去に取得したアドレスが対応しないとという話もありますが,徐々に減っていくでしょうしね。

NTTドコモがメールアドレスをRFC準拠に変更!各社のメールアドレスをまとめてみた | memn0ck.com

NTTドコモは、4月より携帯電話のメールアドレスについて、ルールの変更を行った。  4月1日以降、メールアドレスを新規取得または変更する場合、新ルールが適用される。新ルールでは「○○..○○@docomo.ne.jp」(連続するピリオド)、「○○.@docomo.ne.jp」(@マーク直前のピリオド)といった命名方法が使用不可となる。すでに取得済みのアドレスについては、新ルールは適用されない。

NTTドコモ、メールアドレスのルールを変更 〜 ピリオド連続などが使用不可に | RBB TODAY

こんなのに対応するのはバッドノウハウみたいなもんで不毛きわまりないんだけど、生きてるものは仕方無いからこれをチェックできるように改変する。

続きを読む

Relationが定義されたエレメントツリーごと履歴に保存したい

業務プログラムだとMaster-Detailモデルのエンティティの更新履歴を保存したいなんてのは良くある話。
そこはDBのTriggerあたりを使ってやるのも手ではあるんだけど、もうちょっと手軽にやる方法は無いもんかと。

       |
   \  __  /
   _ (m) _ピコーン
      |ミ|
   /  .`´  \
     ∧_∧  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
    (・∀・∩< モデルごとシリアライズしてテキストで保存しよう
    (つ  丿 \_________
    ⊂_ ノ
      (_)

というはなし。

続きを読む

IIS オート スタート設定による ASP.NET Web アプリケーションの初回実行時のパフォーマンス向上の罠

IIS オート スタート設定による ASP.NET Web アプリケーションの初回実行時のパフォーマンス向上 - THE TRUTH IS OUT THERE - Site Home - MSDN Blogsをやってて罠に嵌りまくった腹いせエントリ。

すいません言い過ぎました。

Windows Azure クラウドサービスで IIS/ASP.NET オートスタートを使う

続いて、この ASP.NET アプリケーションのオートスタートの設定を Windows Azure クラウド サービスを使った Web アプリケーションで有効にする方法をご紹介します。

クラウド サービスでも Web ロールにリモートデスクトップ (RDP) 接続して、上記と同じ手順で設定は可能です。しかしながら、スケールアップなどの際に、増やしたインスタンス一つ一つに RDP 接続して設定を行うのは現実的ではありません。オートスケールなどでインスタンスが自動で増減する場合はなおさらです。このような場合に、Windows Azure クラウドサービスでは、スタートアップタスクと、ロールの初期化時のイベントハンドラを利用することで、上記のオートスタートの設定を行うことができます。

IIS オート スタート設定による ASP.NET Web アプリケーションの初回実行時のパフォーマンス向上 - THE TRUTH IS OUT THERE - Site Home - MSDN Blogs

1. スタートアップタスクで Application Initialization モジュールを有効化する

まず、ASP.NET Web アプリケーションのプロジェクトに Startup.cmd ファイルを追加して、プロパティで [出力ディレクトリにコピー] を [常にコピーする] に設定します。

このStartup.cmdはUTF-8じゃなくてANSIじゃないとダメ。
VisualStudioでやってるとこれ忘れてクソハマる。超注意。

そして、Windows Azure クラウドサービス プロジェクトにある ServiceDefinition.csdef ファイルを開いて、下記の記述(太字部分)を追加します。

<ServiceDefinition ...>
  <WebRole name="WebAppPreload" vmsize="Small">

    <Runtime executionContext="elevated"></Runtime>

    <Startup>
 <Task commandLine="Startup.cmd" executionContext="elevated" taskType="simple" />
 </Startup>

Runtime要素はWebRoleの最初に無いとAzureEmulatorでビシバシ落ちた。

IIS 8.0 Application Initialization module in a Windows Azure Web Role

こっちの記事のサンプルを参考に
WindowsAzure-IISApplicationInitializationModule/ServiceDefinition.csdef at master · sandrinodimattia/WindowsAzure-IISApplicationInitializationModule

この順番にしてる。
何でダメなのかまでは調べてない。

2. アプリケーション プール開始モードと Web サイトのプリロード機能の有効化

続いて、applicationHost.config へ行うアプリケーションプールの開始モードと Web サイトのプリロードの有効化ですが、下記のようなクラスを Web アプリケーションプロジェクトに追加し、Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint クラスの Run メソッドをオーバーライドして、その中でプログラムコードを通して設定します。

using Microsoft.Web.Administration;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace WebApplication1
{
    public class WebRole : RoleEntryPoint
    {
        public override void Run()
        {
            using (var serverManager = new ServerManager())
            {
                var mainSite = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"];
                var mainApplication = mainSite.Applications["/"];
                mainApplication["preloadEnabled"] = true;

                var mainApplicationPool = serverManager.ApplicationPools[mainApplication.ApplicationPoolName];
                mainApplicationPool["startMode"] = "AlwaysRunning";

                serverManager.CommitChanges();
            }

            base.Run();
        }

        public override bool OnStart()
        {
            return base.OnStart();
        }
    }
}

これEmulator Express環境下でがっつり落ちた。
問題はここ

  var mainSite = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"];
  var mainApplication = mainSite.Applications["/"];

どうやらserverManagerが正しくEmulatorExpressのインスタンスを指していないようで、Sitesには"Default Web Site"だけが登録されてた。おそらくIISそのもののデータを引いてるくさい。
その為にmainSite.Applications["/"]がぬるぽで死ぬ。

なのでローカルではここを迂回するようにした。

  var mainSite = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"];
  if (mainSite!=null){
    var mainApplication = mainSite.Applications["/"];

    :
  }

というログ。

jquery.validate(unobsolusive)でエラーになったタブを開く

エラーになってもタブを勝手に開いてくれないのかよ(´・ω・`)

$("#reserveeditform").submit(function () {
    $elem = $(".input-validation-error:first");
    $elem.parents().filter(".collapse").collapse("show");
    //tab上にある
    if ($elem.parents().filter(".tab-pane").length > 0) {
        //対象となるタブのAタグを引っ張りだす
        var tabid = $elem.parents().filter(".tab-pane").first().attr("id");
        $("a[href='#" + tabid + "']").tab("show");
    }
});

ややこしい。

続きを読む

jquery.validate.unobtrusiveでタブなどに隠れたフィールドの評価がされない

なんてこった。

In the new version of jQuery validation plugin 1.9 by default validation of hidden fields ignored. I'm using CKEditor for textarea input field and it hides the field and replace it with iframe. The field is there, but validation disabled for hidden fields. With validation plugin version 1.8.1 everything works as expected.

jQuery Validate - Enable validation for hidden fields - Stack Overflow
続きを読む