SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

正式リリースされたWindows Azureの力

キューを使用したWindows Azureストレージプログラミング

正式リリースされたWindows Azureの力(3)

  • X ポスト
  • このエントリーをはてなブックマークに追加

(10)Workerロールを実装する その1-コンテナとキューの作成

 それでは次に、Workerロールを実装していきましょう。

 最初の手順として、コンテナとキューを作成するコードを、「WorkerRole1」プロジェクト内のWorkerRole.csに次のリスト5のように記述します。

[リスト5]コンテナとキューの作成(WorkerRole.cs)
// … 前略 …

using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
// 追加したusingディレクティブ  *1
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace WorkerRole1
{
    public class WorkerRole : RoleEntryPoint
    {
        public override void Run()
        {
            // ストレージアカウントの取得   *2
            string connectionString = RoleEnvironment.GetConfigurationSettingValue("DataConnectionString");
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

            // ブロブとキュークライアントの作成     *3
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

            // オリジナル画像用コンテナの作成(存在しなければ)     *4
            CloudBlobContainer imagesContainer = blobClient.GetContainerReference("images");
            imagesContainer.CreateIfNotExist();

            // コンテナの公開アクセスの許可レベルを、コンテナに設定     *5
            BlobContainerPermissions permissions = imagesContainer.GetPermissions();
            permissions.PublicAccess = BlobContainerPublicAccessType.Container;
            imagesContainer.SetPermissions(permissions);

            // サムネイル画像用コンテナの作成(存在しなければ)     *6
            CloudBlobContainer thumnailsContainer = blobClient.GetContainerReference("thumnails");
            thumnailsContainer.CreateIfNotExist();

            // コンテナの公開アクセスの許可レベルを、コンテナに設定     *7
            permissions = thumnailsContainer.GetPermissions();
            permissions.PublicAccess = BlobContainerPublicAccessType.Container;
            thumnailsContainer.SetPermissions(permissions);

            // キューの作成(存在しなければ)   *8
            CloudQueue queue = queueClient.GetQueueReference("createthumnails");            
                               queue.CreateIfNotExist();

            // … 以下、手順[11]で説明するので省略 …
        }

        // … 以下、省略 …

    }
}

 リスト中のRunメソッドは、自動生成されたWorkerRole.csの中で、その雛形が定義されています。デフォルトでは次のリスト6のようになっており、開発者はこのメソッド中にキューからメッセージを取り出し処理するコードを記述していきます。

[リスト6]自動生成されるRunメソッドの雛形(WorkerRole.cs)
public override void Run()
{
    // This is a sample worker implementation. Replace with your logic.
    Trace.WriteLine("WorkerRole1 entry point called", "Information");

    while (true)
    {
        Thread.Sleep(10000);
        Trace.WriteLine("Working", "Information");
    }
}

 リスト5の説明に話を戻します。WorkerRole.csには、デフォルトでMicrosoft.WindowsAzure.DiagnosticsとMicrosoft.WindowsAzure.ServiceRuntimeの2つのusingディレクティブが記述されています。それに追加する形で、Windows Azureマネージライブラリの2つのusingディレクティブを追加します(*1)。

 *2*8のコードについては、手順(7)で、WebロールのDefault.aspx.csに記述したコードと全く同じものです。WebロールとWorkerロールは非同期で動作しているので、先に実行されたコードによって、両ロールで使用するコンテナとキューが作成されることになります。あくまでサンプルにおける、便宜的なコードとお考えください。

(11)Workerロールを実装する その2-メッセージの処理

 Workerロール実装の次の手順として、同じWorkerRole.csのRunメソッドに、メッセージを処理するコードを次のリスト7のように追加します。

[リスト7]メッセージの処理(WorkerRole.cs)
public override void Run()
{
    // … 手順[10]で説明した部分なので省略 …

    while (true)
    {
        try
        {
            // メッセージの取得     *9
            CloudQueueMessage message = queue.GetMessage();

            if (message != null)
            {
                // メッセージ内容(ブロブ名)の取得
                string blobName = message.AsString;

                Trace.TraceInformation(string.Format("メッセージの取得: message = '{0}'", blobName));

                // オリジナル画像のダウンロード     *10
                MemoryStream orginStream = new MemoryStream();
                CloudBlob orginBlob = imagesContainer.GetBlobReference(blobName);
                orginBlob.DownloadToStream(orginStream);

                // サムネイル画像の作成     *11
                string option = blobName[blobName.Length - 1].ToString();
                Stream thumbStream = CreateThumbnail(orginStream, option);

                // サムネイル画像のアップロード     *12
                CloudBlob thumbnailBlob = thumnailsContainer.GetBlobReference(blobName);
                thumbnailBlob.UploadFromStream(thumbStream);

                orginStream.Close();
                thumbStream.Close();

                Trace.TraceInformation(string.Format("メッセージの処理: message = '{0}'", blobName));

                // メッセージの削除     *13
                queue.DeleteMessage(message);

                Trace.TraceInformation(string.Format("メッセージの削除: message = '{0}'", blobName));
            }
            else
            {
                // 1秒間待機    *14
                Thread.Sleep(1000);
            }
        }
        catch (Exception ex)
        {
            // 例外発生時は、5秒間待機      *15
            // その後、失敗したメッセージを再度処理する
            Thread.Sleep(5000);

            Trace.TraceError(string.Format("メッセージで例外発生: message = '{0}'", ex.Message));
        }
    }
}

 まず、キューからメッセージを取得します(*9)。

 メッセージが存在すれば、メッセージ内容を元に(これはオリジナル画像URIを意味しているので)ブロブからオリジナル画像をダウンロードします(*10)。

 次に、ダウンロードしたオリジナル画像と、メッセージ内容の最後に付加されているサムネイル画像作成時のオプション指定の情報を元に、サムネイル画像を作成します(*11)。このCreateThumbnailメソッドの実装については、次の手順で扱います。

 次に、作成したサムネイル画像をブロブにアップロードします(*12)。

 最後に、処理を終了したメッセージを削除します(*13)。処理が終わったメッセージを明示的に削除しないと、いつまでもキューに残り続けるので注意してください。

 キューにメッセージが存在しなかった場合には、1秒間待機します(*14)。

 *9*14までの一連の処理が、while(true)のステートメントにより、ずっと繰り返されます。何かの理由で例外が発生した場合でも、キューにはメッセージが残っているので、しばらく待機した後、そのメッセージが再び処理されます。

 なお、Workerロールはユーザーインターフェースを持ちませんので、実行状況の確認やデバッグ時の助けとして、System.Diagnostics.Traceクラスを使用してトレース情報を出力しています。開発環境では、Windows Azureのシミュレーション環境であるDevelopment Fabricを使用して、トレース情報を確認できます。

次のページ
まとめ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
正式リリースされたWindows Azureの力連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 広瀬 嘉久(株式会社ジェイテックジャパン)(ヒロセ ヨシヒサ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5222 2010/06/25 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング