2015-11-19 43 views
5

Sono nuovo per il servizio di assistenza e ho iniziato osservando gli articoli MSDN che trattano l'argomento. Ho iniziato implementando l'esempio Hello World here.Service Fabric - Stateful Service Persistence

ho cambiato la loro implementazione originale RunAsync a:

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); 
} 

Ho anche introdotto un tipo DataObject e hanno esposto una proprietà UpdateDate su quel tipo.

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

Quando eseguo l'applicazione (F5 in Visual Studio 2015), un dataObject esempio (digitato da 1) non si trova nel dizionario così creo uno, impostare UpdateDate, aggiungere al dizionario e impegnare la transazione. Durante il ciclo successivo, trova dataObject (con chiave 1) e imposta UpdateDate, aggiorna l'oggetto nel dizionario e impegna la transazione. Perfezionare.

Ecco la mia domanda. Quando interrompo e riavvia il progetto di servizio (F5 in visual studio 2015) mi aspetterei che alla prima esecuzione di RunAsync venga trovato il dataObject (con chiave 1) ma non lo è. Mi aspetto che tutto lo stato venga svuotato alla sua replica.

Devo fare qualcosa per il servizio stateful per svuotare lo stato interno alla sua replica primaria?

Da quello che ho letto, lo fa sembrare come se tutto questo venisse gestito dal fabric di servizio e che il commit di chiamata (sulla transazione) sia sufficiente. Se trovo la replica primaria (in Service Fabric Explorer-> Vista applicazione) posso vedere che RemoteReplicator_xxx LastACKProcessedTimeUTC viene aggiornato una volta che ho eseguito il commit della transazione (durante l'esecuzione).

Qualsiasi aiuto è molto apprezzato.

Grazie!

-Mark

risposta

4

Questa è una funzione della esperienza di sviluppo locale predefinito in Visual Studio. Se si guarda da vicino la finestra di output dopo aver colpito F5 verrà visualizzato un messaggio come questo:

Visual Studio output window during Service Fabric deployment

lo script di distribuzione rileva che c'è un app esistente dello stesso tipo e la versione già registrato, quindi lo rimuove e distribuisce quello nuovo. In tal modo, vengono rimossi i dati associati alla vecchia applicazione.

Hai un paio di opzioni per affrontare questo.

In produzione, è necessario eseguire un application upgrade per distribuire in modo sicuro il codice aggiornato mantenendo lo stato. Ma aggiornare costantemente le tue versioni mentre fai una rapida iterazione sulla tua casella di sviluppo può essere noioso.

Un'alternativa è di capovolgere la proprietà del progetto "Mantieni dati all'avvio" su "Sì". Verrà automaticamente eseguito il bump di tutte le versioni del pacchetto dell'applicazione generato (senza toccare le versioni nella tua sorgente) e quindi eseguirà un aggiornamento dell'app per tuo conto.

enter image description here

Nota che a causa di alcune delle verifiche di sistema inerenti al percorso di aggiornamento, questa opzione di distribuzione è probabile che sia un po 'più lento di quello predefinito rimuovere e sostituzione. Tuttavia, quando si calcola il tempo necessario per ricreare i dati del test, spesso è un lavaggio.

+0

Grazie Sean. Le proprietà del mio progetto (sul progetto sfproj) non mostrano un gruppo di applicazioni nella finestra Proprietà. Ho forse bisogno di un aggiornamento vs2015 o ...? Ho installato gli strumenti Fabric del servizio di Visual Studio (il sdk dalla pagina di avvio). Grazie ancora! – markondotnet

+0

Quando hai installato l'SDK? Questa funzionalità è nuova nella versione di anteprima pubblica rilasciata ieri. –

+0

L'ho installato la scorsa domenica e ho appena notato oggi (nelle notifiche vs2015) che la versione 2.8 era fuori (a partire da ieri) quindi l'ho installata. Ancora nessuna opzione "Preserva dati all'avvio" sulle proprietà del progetto. – markondotnet

3

È necessario pensare a ReliableDictionary come a contenere raccolte di oggetti anziché a una raccolta di riferimenti. Cioè, quando aggiungi un "oggetto" al dizionario, devi pensare che stai consegnando l'oggetto completamente; e non devi più modificare lo stato di questo oggetto nel più. Quando chiedi a ReliableDictionary per un "oggetto", ti restituisce un riferimento al suo oggetto interno. Il riferimento viene restituito per motivi di prestazioni e sei libero di LEGGERE lo stato dell'oggetto. (Sarebbe bello se il CLR supportasse gli oggetti di sola lettura ma non lo fosse.) Tuttavia, NON DEVI MODIFICARE lo stato dell'oggetto (o chiamare qualsiasi metodo che modifichi lo stato dell'oggetto) come si farebbe con la modifica delle strutture di dati interne del dizionario che corrompe il suo stato.

Per modificare lo stato dell'oggetto, DEVI eseguire una copia dell'oggetto a cui fa riferimento il riferimento restituito. Puoi farlo serializzando/deserializzando l'oggetto o con altri mezzi (come la creazione di un intero nuovo oggetto e la copia del vecchio stato sul nuovo oggetto). Quindi, scrivi il NUOVO OGGETTO nel dizionario. In una versione futura di Service Fabric, intendiamo migliorare le API di ReliableDictionary per rendere più visibile questo schema di utilizzo richiesto.