2015-11-19 13 views
5

サービスファブリックを初めて使用し、トピックを扱うMSDNの記事を見て始めました。 Hello Worldサンプルhereを実装することから始めました。サービスファブリック - ステートフルサービスの永続性

私はに元のRunAsyncの実装を変更:私もDataObjectのタイプを導入し、その種類にUpdateDateプロパティを公開している

var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<int, DataObject>>("myDictionary"); 

while (!cancellationToken.IsCancellationRequested) 
{ 
    DataObject dataObject; 

    using (var tx = this.StateManager.CreateTransaction()) 
    { 
     var result = await myDictionary.TryGetValueAsync(tx, 1); 

     if (result.HasValue) 
      dataObject = result.Value; 
     else 
      dataObject = new DataObject(); 
     // 
     dataObject.UpdateDate = DateTime.Now; 
     // 
     //ServiceEventSource.Current.ServiceMessage(
     // this, 
     // "Current Counter Value: {0}", 
     // result.HasValue ? result.Value.ToString() : "Value does not exist."); 

     await myDictionary.AddOrUpdateAsync(tx, 1, dataObject, ((k, o) => dataObject)); 

     await tx.CommitAsync(); 
    } 
    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); 
} 

。私はアプリ(Visual Studioの2015年F5)を実行すると、私は1つを作成するよう

[DataContract(Namespace = "http://www.contoso.com")] 
public class DataObject 
{ 
    [DataMember] 
    public DateTime UpdateDate { get; set; } 
} 

、(1としてキー)のDataObjectインスタンスが辞書に見つからない、UpdateDateを設定し、辞書に追加し、トランザクションをコミットします。次のループでは、データオブジェクト(キーとして1)を検索し、UpdateDateを設定し、辞書にオブジェクトを更新してトランザクションをコミットします。完璧。

ここに私の質問です。私がサービスプロジェクト(Visual Studio 2015のF5)を停止して再起動すると、runAsyncの最初の反復でdataObject(キーとして1)が見つかりましたが、そうではないことが予想されます。私はすべての州がそのレプリカに流されることを期待する。

ステートフルサービスが内部状態をプライマリレプリカにフラッシュするために何かする必要がありますか?

私が読んだところでは、このすべてがサービスファブリックによって処理され、トランザクションでのコミットを呼び出すだけで十分であるように見えます。 (サービスファブリックエクスプローラ - >アプリケーションビューで)プライマリレプリカを検索すると、トランザクションをコミットすると(ステップ実行すると)RemoteReplicator_xxx LastACKProcessedTimeUTCが更新されることがわかります。

ご協力いただきまして誠にありがとうございます。

ありがとうございました!

-mark

答えて

4

これは、Visual Studioのデフォルトのローカル開発経験の関数です。

Visual Studio output window during Service Fabric deployment

展開スクリプトが既に登録されている同じ種類とバージョンの既存のアプリがありますことを検出し、それはそれを削除します。あなたはF5キーを打った後密接に出力ウィンドウを見る場合は、このようなメッセージが表示されます新しいものをデプロイします。その際、古いアプリケーションに関連するデータは削除されます。

これに対処するには、いくつかのオプションがあります。

生産時には、application upgradeを実行して、状態を維持しながら安全に更新されたコードをロールアウトします。しかし、あなたのdevのボックスで迅速な反復をしながらあなたのバージョンを常に更新するのは面倒なことがあります。

代替案は、プロジェクトプロパティ "Start Data on Start"を "Yes"にフリップすることです。これにより、生成されたアプリケーションパッケージのすべてのバージョンが(ソースのバージョンに触れることなく)自動的にバンプされ、あなたの代わりにアプリケーションのアップグレードが実行されます。

enter image description here

ため、アップグレードパスに固有のシステムチェックのいくつかの、この展開オプションはデフォルト置き換える削除-と-よりも少し遅くなる可能性があることに注意してください。しかし、テストデータを再作成するのにかかる時間を考慮すると、しばしば洗い流されます。

+0

ありがとうSean。私のプロジェクトプロパティ(sfprojプロジェクト上)は、[プロパティ]ウィンドウにアプリケーショングループを表示しません。 vs2015のアップデートが必要なのでしょうか? Visual Studio Service Fabric Toolsがインストールされています(開始ページのsdk)。再度、感謝します! – markondotnet

+0

いつSDKをインストールしましたか?この機能は、昨日公開された公開プレビュー版の新機能です。 –

+0

私はこれを過去の日曜日にインストールしましたが、今日(vs2015通知で)v2.8が(昨日のように)出ていたので、私はそれをインストールしました。まだプロジェクトのプロパティで「開始時にデータを保持する」オプションはありません。 – markondotnet

3

ReliableDictionaryは、参照のコレクションではなくオブジェクトのコレクションを保持するものと考える必要があります。つまり、辞書に「オブジェクト」を追加すると、オブジェクトを完全に取り除いていると考える必要があります。もはやこのオブジェクトの状態を変更してはいけません。 ReliableDictionaryに "オブジェクト"を要求すると、内部オブジェクトへの参照が返されます。パフォーマンス上の理由から参照が返され、オブジェクトの状態を自由に読み取ることができます。 (CLRが読み取り専用のオブジェクトをサポートしていても、そうでない場合は、CLRがサポートされていれば素晴らしいでしょう)しかし、内部データ構造を変更するときは、オブジェクトの状態を変更してはいけません(または、その状態を破損させることがあります。

オブジェクトの状態を変更するには、返された参照が指すオブジェクトのコピーを作成する必要があります。これを行うには、オブジェクトをシリアライズ/デシリアライズするか、他の手段(新しいオブジェクト全体を作成し、古いオブジェクトを新しいオブジェクトにコピーするなど)を実行します。次に、NEW OBJECTを辞書に書き込みます。 Service Fabricの将来のバージョンでは、ReliableDictionaryのAPIを改良して、この必要なパターンをより発見しやすくするつもりです。