今更感漂うが、テーブル・ストレージの「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
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」にサンプルらしき記述があるが、具体的な使用方法は分かっていない。ご存じの方が居たら是非紹介して頂きたい。
参考文献
- MSDN(英語) > Query Timeout and Pagination
- MSDN Code Gallery > Paging Windows Azure Tables
- 特集 Windows Azureストレージ開発入門(前編)> 初めてのWindows Azureテーブル・ストレージ開発
- Neil氏ブログ > Queries in Azure Tables
*1:Windows Azure SDKはREST 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