normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

Windows Azure テーブル・ストレージの「Continuation token」について

今更感漂うが、テーブル・ストレージの「Continuation token」について述べたいと思う。

「Continuation token」とは

テーブル・ストレージを取り扱うために必要なデータであり、以下の3種類が存在する。

  • x-ms-continuation-NextTableName
  • x-ms-continuation-NextPartitionKey
  • x-ms-continuation-NextRowKey

賢明な方はプロパティ名を見て察しがついたかもしれないが、こ奴らは「テーブル・ストレージ用のREST APIのカスタムヘッダ*1」であり、主にテーブル・ストレージのページング処理を行うために利用する。

「ページング処理になんでこんなものが必要なんだ?」と思うかたも多いだろうが、テーブル・ストレージに対して発行したクエリで返されるエンティティの数は、以下のいずれかの理由で制限される*2

  • クエリで返されるエンティティの数がアプリケーション側で指定されている
  • クエリで返されるエンティティの数が最大数(現在は1000個)を超えている
  • クエリの実行時間が5秒を超えている

これらの特性を克服し、テーブル・ストレージを利用したページング処理を実現するためには、「Continuation token」を活用する必要がある。

「Continuation token」の利用方法

サンプルコードがMSDN Code Gallery > Paging Windows Azure Tablesで公開されているが、残念ながら公開日が古いため、Windows Azure SDK 1.0以降に対応していない*3

せっかくなので、最新版のWindows Azure SDKに対応した「PagingTableStorageCloudService.zip」を作成したので、そこからコードを抜粋して解説する。

以下は単純な例であるが、「Continuation tokenの読取」と「Continuation tokenを付加したリクエストの発行」を実現している。

//TableServiceEntityを継承したサービスコンテキストを定義
commentContext =
    new CommentContext(
    cloudStorageAccount.TableEndpoint.ToString(),
    cloudStorageAccount.Credentials);

///1.Continuation tokenの読取 
// 三メッセージ取得するクエリを「Microsoft.WindowsAzure.StorageClient.DataServiceQuery」型にキャスト
var query = (DataServiceQuery<CommentEntity>)(commentContext.CommentTable.Take(3));

// QueryOperationResponse型にキャストして、HTTPのカスタムヘッダを読み取る
var qor = (QueryOperationResponse)res;
string nextPartition = null;
string nextRow = null;
qor.Headers.TryGetValue("x-ms-continuation-NextPartitionKey", out nextPartition);
qor.Headers.TryGetValue("x-ms-continuation-NextRowKey", out nextRow);


///2.Continuation tokenを付加したリクエストの発行
// NextPartitionKeyとNextRowKeyの値をリクエストパラメータに追加
query = query.AddQueryOption("NextPartitionKey", nextPartition).AddQueryOption("NextRowKey", nextRow);

//テーブル・ストレージに対するリクエストの発行
var res = query.Execute();

ソースコードを確認して頂ければ分かると思うが、残念ながらContinuation tokeはAzure SDK側でプロパティとして定義はされていない…?。プログラマ側でカスタムヘッダを読み取り、独自に対応する必要がありそうにみえる。

ところが…

てっきり「Continuation token」はAzure SDK内に含まれないものだと思っていたが、以下のクラスを発見した。

  • Microsoft.WindowsAzure.StorageClient.ResultContinuation
  • Microsoft.WindowsAzure.StorageClient.ResultSegment

どうやら、「ResultSegment」クラスが「Continuation token」の役割を担うと推察できる。ここから、「Microsoft.WindowsAzure.StorageClient.CloudTableQuery」クラスが、「ResultSegment」クラスを返すメソッドを用意しているのではないかと考えた。一通りのメンバを眺めてみたところ、どうやら以下のメソッドが該当するらしい。

public Microsoft.WindowsAzure.StorageClient.ResultSegment<TElement> EndExecuteSegmented(System.IAsyncResult asyncResult)
    Member of Microsoft.WindowsAzure.StorageClient.CloudTableQuery<TElement>

Summary:
Returns the first segment of results of an asynchronous request to execute a query.

Parameters:
asyncResult: The reference to the pending asynchronous request to finish.

Returns:
A Microsoft.WindowsAzure.StorageClient.ResultSegment<TElement> that contains the first segment of results.

参考文献の「Neil氏ブログ > Queries in Azure Tables」にサンプルらしき記述があるが、具体的な使用方法は分かっていない。ご存じの方が居たら是非紹介して頂きたい。

参考文献

*1:Windows Azure SDKREST APIをラッピングしている

*2:詳細な内容については「特集[http://www.atmarkit.co.jp/fdotnet/dnfuture/winazurestorage_01/winazurestorage_01_02.html:title=Windows Azureストレージ開発入門(前編)>初めてのWindows Azureテーブル・ストレージ開発]」を参照して頂きたい

*3:現在の最新版はWindows Azure SDK 1.1