public async Task <TValue> AddOrUpdateAsync(ITransaction tx, TKey key, Func <TKey, TValue> addValueFactory, Func <TKey, TValue, TValue> updateValueFactory) { if (reliableDictionary == null) { await InitializeReliableDictionary(); } return(await reliableDictionary.AddOrUpdateAsync(tx, key, addValueFactory, updateValueFactory)); }
private async Task ProcessOrdersAsync( Order order, IReliableDictionary <OrderQueueKey, OrderQueue> storage, OrderQueueKey orderQueueKey, OrderQueueKey oppositeOrderQueueKey) { using (var tx = _stateManager.CreateTransaction()) { var orderQueue = await storage.GetOrAddAsync( tx, orderQueueKey, new OrderQueue(order.CurrencyPair, order.Side)); var oppositeOrderQueue = await storage.GetOrAddAsync( tx, oppositeOrderQueueKey, new OrderQueue(order.CurrencyPair, order.Side == Side.Buy ? Side.Sell : Side.Buy)); while (true) { var oppositeOrder = oppositeOrderQueue.Peek(); if (oppositeOrder == null) { break; } var matched = _ordersMatchingRule.IsMatched(order, oppositeOrder); if (matched) { matched = _ordersMatchingRule.IsMatched(order, oppositeOrder); if (matched) { ProcessOrders(order, orderQueue, oppositeOrder, oppositeOrderQueue); } else { // process further if some thread is here continue; } } if (order.IsClosed || !matched || oppositeOrderQueue.IsEmpty) { break; } } await storage.AddOrUpdateAsync(tx, orderQueueKey, orderQueue, (key, old) => orderQueue); await storage.AddOrUpdateAsync(tx, oppositeOrderQueueKey, oppositeOrderQueue, (key, old) => orderQueue); await tx.CommitAsync(); } }
private async Task AppendAsync(string fullPath, Stream sourceStream, CancellationToken cancellationToken) { fullPath = ToFullPath(fullPath); using (ServiceFabricTransaction tx = GetTransaction()) { IReliableDictionary <string, byte[]> coll = await OpenCollectionAsync().ConfigureAwait(false); //create a new byte array with byte[] extra = sourceStream.ToByteArray(); ConditionalValue <byte[]> value = await coll.TryGetValueAsync(tx.Tx, fullPath).ConfigureAwait(false); int oldLength = value.HasValue ? value.Value.Length : 0; byte[] newData = new byte[oldLength + extra.Length]; if (value.HasValue) { Array.Copy(value.Value, newData, oldLength); } Array.Copy(extra, 0, newData, oldLength, extra.Length); //put new array into the key await coll.AddOrUpdateAsync(tx.Tx, fullPath, extra, (k, v) => extra).ConfigureAwait(false); //commit the transaction await tx.CommitAsync().ConfigureAwait(false); } }
private async Task ConsumeBufferBlock(CancellationToken cancellationToken) { while (true) { cancellationToken.ThrowIfCancellationRequested(); if (await this._simDataBuffer.OutputAvailableAsync(cancellationToken)) { var processedCount = 0; while (true) { using (var tx = this.StateManager.CreateTransaction()) { var evt = this._simDataBuffer.Receive(); await this.ProcessEvent(evt, cancellationToken); await _propertiesDictionary.AddOrUpdateAsync(tx, LASTINDEXPROPERTYNAME, evt.Id, (key, value) => evt.Id); if (processedCount++ >= MAXEVENTSPERITERATION || this._simDataBuffer.Count == 0) { await tx.CommitAsync(); break; } } } } } }
public async Task AddLoadAsync(ITransaction tx, Uri collectionName, IEnumerable <LoadMetric> metrics) { IReliableDictionary <string, List <LoadMetric> > metricDictionary = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, List <LoadMetric> > >(this.metricStoreName); await metricDictionary.AddOrUpdateAsync( tx, collectionName.ToString(), metrics.ToList(), (key, value) => { List <LoadMetric> currentMetrics = new List <LoadMetric>(); foreach (LoadMetric newMetric in metrics) { LoadMetric current = value.Find(x => String.Equals(x.Name, newMetric.Name, StringComparison.OrdinalIgnoreCase)); if (current == null) { currentMetrics.Add(newMetric); } else { currentMetrics.Add(new LoadMetric(current.Name, current.Value + newMetric.Value)); } } return(currentMetrics); }); }
/// <summary> /// Called to add a metric to the watchdog. /// </summary> /// <param name="mcm">MetricCheck metric.</param> /// <returns>Task instance.</returns> /// <exception cref="ArgumentException">ServiceName parameter within the HealthCheck instance does not exist.</exception> public async Task <bool> AddMetricAsync(MetricCheck mcm) { // Get the required dictionaries. IReliableDictionary <string, MetricCheck> hcDict = await this.GetMetricCheckDictionaryAsync().ConfigureAwait(false); try { // Create a transaction. using (ITransaction tx = this._service.StateManager.CreateTransaction()) { // Add or update the HealthCheck item in the dictionary. await hcDict.AddOrUpdateAsync(tx, mcm.Key, mcm, (k, v) => { return(mcm); }, this._timeout, this._token).ConfigureAwait(false); await tx.CommitAsync(); Interlocked.Increment(ref this._metricCount); } } catch (FabricObjectClosedException) { this._service.RefreshFabricClient(); return(true); } catch (TimeoutException ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddMetricAsync)); } catch (FabricTransientException ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddMetricAsync)); } return(false); }
private async Task<bool> loadConfigFromBlob() { try { string connectionString = blobConnection; string tableName = blobTableName; string partitionKey = blobPartitionkey; CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(connectionString); CloudTableClient tableClient = cloudStorageAccount.CreateCloudTableClient(); CloudTable cloudTable = tableClient.GetTableReference(tableName); TableQuery<ExternalResource> query = new TableQuery<ExternalResource>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey)); var result = await cloudTable.ExecuteQuerySegmentedAsync(query, null); var listResources = result.ToList(); IReliableDictionary<string, ExternalResource> rsDict = await StateManagerHelper.GetExternalResourceDictAsync(this.StateManager); using (ITransaction tx = this.StateManager.CreateTransaction()) { for (int i = 0; i < listResources.Count; i++) { var item = listResources[i]; var exists = await rsDict.TryGetValueAsync(tx, item.RowKey); if (exists.HasValue) { if (false == exists.Value.ETag.Equals(item.ETag)) { item.IsUpdate = true; } else { item.IsUpdate = false; } } else { item.IsUpdate = true; } await rsDict.AddOrUpdateAsync(tx, item.RowKey, item, (k, v) => { return item; }, TimeSpan.FromSeconds(5), CancellationToken.None); } await tx.CommitAsync().ConfigureAwait(false); } } catch (Exception ex) { ServiceEventSource.Current.Exception("Load resource from blob failed", ex.Message, ex.StackTrace); return false; } return true; }
private async Task WriteAsync(NetCore.Blobs.Blob blob, Stream sourceStream, CancellationToken cancellationToken) { string fullPath = ToFullPath(blob); byte[] value = sourceStream.ToByteArray(); using (ServiceFabricTransaction tx = GetTransaction()) { IReliableDictionary <string, byte[]> coll = await OpenCollectionAsync().ConfigureAwait(false); IReliableDictionary <string, BlobMetaTag> metaColl = await OpenMetaCollectionAsync().ConfigureAwait(false); var meta = new BlobMetaTag { LastModificationTime = DateTimeOffset.UtcNow, Length = value.LongLength, Md = value.GetHash(HashType.Md5).ToHexString() }; await metaColl.AddOrUpdateAsync(tx.Tx, fullPath, meta, (k, v) => meta).ConfigureAwait(false); await coll.AddOrUpdateAsync(tx.Tx, fullPath, value, (k, v) => value).ConfigureAwait(false); await tx.CommitAsync().ConfigureAwait(false); } }
private async Task WriteAsync(string id, Stream sourceStream) { id = ToId(id); byte[] value = sourceStream.ToByteArray(); using (ServiceFabricTransaction tx = GetTransaction()) { IReliableDictionary <string, byte[]> coll = await OpenCollectionAsync(); IReliableDictionary <string, BlobMetaTag> metaColl = await OpenMetaCollectionAsync(); var meta = new BlobMetaTag { LastModificationTime = DateTimeOffset.UtcNow, Length = value.LongLength, Md = value.GetHash(HashType.Md5).ToHexString() }; await metaColl.AddOrUpdateAsync(tx.Tx, id, meta, (k, v) => meta); await coll.AddOrUpdateAsync(tx.Tx, id, value, (k, v) => value); await tx.CommitAsync(); } }
public async Task StopAsync() { IReliableDictionary <string, CurrentState> chaosServiceState = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, CurrentState> >(StringResource.ChaosServiceStateKey); bool shouldCancel = false; using (ITransaction tx = this.StateManager.CreateTransaction()) { ConditionalValue <CurrentState> currentStateResult = await chaosServiceState.TryGetValueAsync(tx, StringResource.ChaosServiceStateKey, LockMode.Update); if (currentStateResult.HasValue && currentStateResult.Value == CurrentState.Running) { await chaosServiceState.AddOrUpdateAsync( tx, StringResource.ChaosServiceStateKey, CurrentState.Stopped, (key, existingValue) => CurrentState.Stopped); shouldCancel = true; } await tx.CommitAsync(); } if (shouldCancel && this.stopEventTokenSource != null && !this.stopEventTokenSource.IsCancellationRequested) { this.stopEventTokenSource.Cancel(); } }
/// <summary> /// Starts the test. /// </summary> /// <returns></returns> public async Task StartAsync() { IReliableDictionary <string, CurrentState> chaosServiceState = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, CurrentState> >(StringResource.ChaosServiceStateKey); using (ITransaction tx = this.StateManager.CreateTransaction()) { ConditionalValue <CurrentState> currentStateResult = await chaosServiceState.TryGetValueAsync(tx, StringResource.ChaosServiceStateKey, LockMode.Update); if (currentStateResult.HasValue && (currentStateResult.Value == CurrentState.Stopped || currentStateResult.Value == CurrentState.None)) { await chaosServiceState.AddOrUpdateAsync( tx, StringResource.ChaosServiceStateKey, CurrentState.Running, (key, existingValue) => CurrentState.Running); } await tx.CommitAsync(); } }
private async Task SetEntityInternalAsync <TU>( IReliableDictionary <TKey, TU> dictionary, TKey key, TU entity, Func <TKey, TU, TU> updateIfExisting, CancellationToken token) { // Handling FabricNotPrimaryException and re-throwing it as Operation cancelled. This is really to // to get around the platform gap where the store and the runtime sends their own set of notification // to user when current replica is no longer primary. The store sends this by throwing this particular // exception for any write and runtime will signal the cancellation token. In case of both, I need to behave the same // i.e. don't do any further writes and just stop asap. Easiest way I can find this is by failing all writes // with operation cancelled exception. The app is already handling this exception and treating it as if cancellation token // has been signalled. // That said, not the most ideal and I've an email thread with Runtime folks. using (var tx = this.stateManager.CreateTransaction()) { await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( () => dictionary.AddOrUpdateAsync(tx, key, entity, updateIfExisting), token).ConfigureAwait(false); await tx.CommitAsync().ConfigureAwait(false); } }
/// <summary> /// Registers an entity as observable for a given topic. /// </summary> /// <param name="topic">The topic.</param> /// <param name="entityId">The entity id.</param> /// <returns>The asynchronous result of the operation.</returns> public async Task RegisterObservableAsync(string topic, EntityId entityId) { if (string.IsNullOrWhiteSpace(topic)) { throw new ArgumentException($"The {nameof(topic)} parameter cannot be null.", nameof(topic)); } if (entityId == null) { throw new ArgumentException($"The {nameof(entityId)} parameter cannot be null.", nameof(entityId)); } try { IReliableDictionary <string, EntityId> observablesDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, EntityId> >(topic); string entityUri = entityId.EntityUri.ToString(); using (ITransaction transaction = this.StateManager.CreateTransaction()) { ConditionalValue <EntityId> result = await observablesDictionary.TryGetValueAsync(transaction, entityUri); if (!result.HasValue) { await observablesDictionary.AddOrUpdateAsync(transaction, entityUri, entityId, (k, v) => v); ServiceEventSource.Current.Message($"Observable successfully registered.\r\n[Observable]: {entityId}\r\n[Publication]: Topic=[{topic}]"); } await transaction.CommitAsync(); } } catch (Exception ex) { ServiceEventSource.Current.Error(ex); throw; } }
public async Task <bool> AddVehicle(VehicleModel vehicleModel, CancellationToken cancellationToken) { try { cancellationToken.ThrowIfCancellationRequested(); IReliableDictionary <Guid, VehicleModel> vehicleDictionary = await GetVehicleModelsFromReliableStateAsync(); using (ITransaction tx = _stateManager.CreateTransaction()) { var res = await vehicleDictionary.AddOrUpdateAsync (tx : tx, key : vehicleModel.VehicleID, addValue : vehicleModel, updateValueFactory : (key, value) => VehicleModelUpdateFactory(value, vehicleModel)); await tx.CommitAsync(); }; return(true); } catch (Exception) { throw; } }
/// <summary> /// The platform calls this method when an instance of your service is placed and ready to execute. /// </summary> /// <param name="cancellationToken"> /// The system uses a cancellation token to signal your service when it's time to stop running. /// </param> /// <returns></returns> protected override async Task RunAsync(CancellationToken cancellationToken) { IReliableDictionary <int, CustomObject> dictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <int, CustomObject> >("dictionary1"); int i = 1; while (!cancellationToken.IsCancellationRequested) { using (ITransaction tx = this.StateManager.CreateTransaction()) { await dictionary.AddOrUpdateAsync(tx, i, new CustomObject() { Data = i }, (k, v) => new CustomObject() { Data = v.Data + 1 }); await tx.CommitAsync(); } ServiceEventSource.Current.ServiceMessage( this, "Total Custom Objects: {0}. Data Average: {1}", await dictionary.GetCountAsync(), dictionary.Average(item => item.Value.Data)); i = i % 10 == 0 ? 1 : i + 1; await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); } }
public async Task <IActionResult> Put(string name) { IReliableDictionary <string, int> votesDictionary = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, int> >("counts"); using (ITransaction tx = this.stateManager.CreateTransaction()) { await votesDictionary.AddOrUpdateAsync(tx, name, 1, (key, oldvalue) => { if (oldvalue < 1) { logger.Information("Create new vote option {VotingOption} vote count {VoteCount}", name, (oldvalue + 1)); } else { logger.Information("Vote for option {VotingOption} vote count {VoteCount}", name, (oldvalue + 1)); } return(oldvalue + 1); }); await tx.CommitAsync(); } return(new OkResult()); }
/// <summary> /// This is the main entry point for your service replica. /// This method executes when this replica of your service becomes primary and has write status. /// </summary> /// <param name="cancellationToken">Canceled when Service Fabric needs to shut down this service replica.</param> protected override async Task RunAsync(CancellationToken cancellationToken) { try { //IEnumerable<QueueMessage> qm = await _receiver.ReceiveMessagesAsync(100); await _publisher.PutMessagesAsync(new[] { QueueMessage.FromText("content at " + DateTime.UtcNow) }); //qm = await _receiver.ReceiveMessagesAsync(100); //separate writes await _blobs.WriteTextAsync("one", "test text 1"); await _blobs.WriteTextAsync("two", "test text 2"); //with transaction object using (ITransaction tx = await _blobs.OpenTransactionAsync()) { await _blobs.WriteTextAsync("three", "test text 1"); await _blobs.WriteTextAsync("four", "test text 2"); await tx.CommitAsync(); } IEnumerable <BlobId> keys = await _blobs.ListAsync(null); string textBack = await _blobs.ReadTextAsync("one"); textBack = await _blobs.ReadTextAsync("two"); } catch (Exception ex) { throw; } IReliableDictionary <string, long> myDictionary = await StateManager.GetOrAddAsync <IReliableDictionary <string, long> >("myDictionary"); while (true) { cancellationToken.ThrowIfCancellationRequested(); using (SFT tx = this.StateManager.CreateTransaction()) { Microsoft.ServiceFabric.Data.ConditionalValue <long> result = await myDictionary.TryGetValueAsync(tx, "Counter"); ServiceEventSource.Current.ServiceMessage(this.Context, "Current Counter Value: {0}", result.HasValue ? result.Value.ToString() : "Value does not exist."); await myDictionary.AddOrUpdateAsync(tx, "Counter", 0, (key, value) => ++ value); // If an exception is thrown before calling CommitAsync, the transaction aborts, all changes are // discarded, and nothing is saved to the secondary replicas. await tx.CommitAsync(); } await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); } }
public async Task RemoveTask(ITask task) { if (!m_tx.TryGetValue(task, out var tx)) { return; } try { await ServiceFabricUtils.DoWithTimeoutRetry( async() => await m_tagCounter.AddOrUpdateAsync(tx, task.Tag, _ => 0, (k, v) => v - 1, TimeSpan.FromSeconds(10), m_cancel), async() => await tx.CommitAsync()); } finally { ReleaseTx(task, tx); } }
/// <summary> /// Called to add a health check to the watchdog. /// </summary> /// <param name="hcm"></param> /// <returns>Task instance.</returns> /// <exception cref="ArgumentException">ServiceName parameter within the HealthCheck instance does not exist.</exception> public async Task <bool> AddHealthCheckAsync(HealthCheck hcm) { // Validate that the service name actually exists within the cluster. If it doesn't, throw an error. if (false == await this.ValidateServiceExistsAsync(hcm.ServiceName, hcm.Partition).ConfigureAwait(false)) { throw new ArgumentException($"Service '{hcm.ServiceName?.AbsoluteUri}' does not exist within the cluster.", nameof(hcm.ServiceName)); } // Get the required dictionaries. IReliableDictionary <string, HealthCheck> hcDict = await this.GetHealthCheckDictionaryAsync().ConfigureAwait(false); try { // Create a transaction. using (ITransaction tx = this._service.StateManager.CreateTransaction()) { // Add or update the HealthCheck item in the dictionary. await hcDict.AddOrUpdateAsync(tx, hcm.Key, hcm, (k, v) => { return(hcm); }, this._timeout, this._token).ConfigureAwait(false); Interlocked.Increment(ref this._healthCheckCount); // Create the HealthCheckScheduleItem instance and save it. if (await this.SaveAsync(tx, new WatchdogScheduledItem(DateTimeOffset.UtcNow, hcm.Key)).ConfigureAwait(false)) { await tx.CommitAsync().ConfigureAwait(false); return(true); } } } catch (FabricObjectClosedException ex) { //TODO: ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddHealthCheckAsync)); ServiceEventSource.Current.Message(ex.Message + ex.GetType().Name + nameof(this.AddHealthCheckAsync)); } catch (TimeoutException ex) { //TODO: ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddHealthCheckAsync)); ServiceEventSource.Current.Message(ex.Message + ex.GetType().Name + nameof(this.AddHealthCheckAsync)); } catch (FabricTransientException ex) { //TODO: ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddHealthCheckAsync)); ServiceEventSource.Current.Message(ex.Message + ex.GetType().Name + nameof(this.AddHealthCheckAsync)); } catch (FabricException ex) { //TODO: ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddHealthCheckAsync)); ServiceEventSource.Current.Message(ex.Message + ex.GetType().Name + nameof(this.AddHealthCheckAsync)); } catch (Exception ex) { //TODO: ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddHealthCheckAsync)); ServiceEventSource.Current.Message(ex.Message + ex.GetType().Name + nameof(this.AddHealthCheckAsync)); } return(false); }
/// <summary> /// Run a background processing task on the partition's primary replica. /// </summary> /// <param name="cancellationToken">The token to monitor for cancellation requests. Implementers should take special care to honor the cancellationToken promptly, as delay in doing so may impact service availability.</param> /// <returns>A task that represents the background processing operation.</returns> protected override async Task RunAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { EntityId entityId; switch (this.Partition.PartitionInfo.Kind) { case ServicePartitionKind.Singleton: entityId = new EntityId(this.Context.ServiceName); break; case ServicePartitionKind.Int64Range: Int64RangePartitionInformation in64Range = (Int64RangePartitionInformation)this.Partition.PartitionInfo; entityId = new EntityId(in64Range.LowKey, this.Context.ServiceName); break; default: throw new Exception(Constants.NamedPartitionsNotSupported); } IReliableDictionary <string, EntityId> entityIdDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, EntityId> >(Constants.EntityIdDictionary); using (ITransaction transaction = this.StateManager.CreateTransaction()) { await entityIdDictionary.AddOrUpdateAsync(transaction, Constants.EntityIdKey, entityId, (k, v) => v); await transaction.CommitAsync(); } ServiceEventSource.Current.Message($"{entityId} activated."); break; } catch (FabricTransientException ex) { ServiceEventSource.Current.Error(ex); } catch (AggregateException ex) { foreach (Exception e in ex.InnerExceptions) { ServiceEventSource.Current.Error(e); } throw; } catch (Exception ex) { ServiceEventSource.Current.Error(ex); throw; } } while (!cancellationToken.IsCancellationRequested) { await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); } }
private async Task <bool> BackupCallbackAzureAsync(BackupInfo backupInfo) { string backupId = Guid.NewGuid().ToString(); CancellationToken cancellationToken = default(CancellationToken); long totalBackupCount; IReliableDictionary <int, long> countDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <int, long> >(this.countDictionaryName); using (ITransaction txn = this.StateManager.CreateTransaction()) { long count = await countDictionary.AddOrUpdateAsync(txn, 0, 0, (key, oldValue) => { return(oldValue + 1); }); totalBackupCount = count; await txn.CommitAsync(); } ServiceEventSource.Current.Message("Backup count dictionary updated: " + totalBackupCount); if ((totalBackupCount % 10) == 0) { //Store no more than 10 backups at a time - the actual max might be a bit more than 10 since more backups could have been created when deletion was taking place. Keeps behind 5 backups. await this.backupStore.DeleteBackupsAzureAsync(cancellationToken); } if ((totalBackupCount > 10) && (DateTime.Now.Second % 20) == 0) { //Let's simulate a data loss every time the time is a multiple of 20 seconds, and a backup just completed. ServiceEventSource.Current.ServiceMessage(this, "Restore Started"); using (FabricClient fabricClient = new FabricClient()) { PartitionSelector partitionSelector = PartitionSelector.PartitionIdOf( this.ServiceInitializationParameters.ServiceName, this.ServiceInitializationParameters.PartitionId); await fabricClient.ServiceManager.InvokeDataLossAsync(partitionSelector, DataLossMode.PartialDataLoss, cancellationToken); } } ServiceEventSource.Current.Message("Backing up from directory, ID : " + backupInfo.Directory + " *** " + backupId); try { await this.backupStore.UploadBackupFolderAsync(backupInfo.Directory, backupId, CancellationToken.None); } catch (Exception e) { ServiceEventSource.Current.ServiceMessage(this, "Uploading to backup folder failed: " + "{0} {1}" + e.GetType() + e.Message); } return(true); }
public async Task AddProduct(Product product) { IReliableDictionary <Guid, Product> products = await GetReliableProductsCollection(); using (var tx = _stateManager.CreateTransaction()) { await products.AddOrUpdateAsync(tx, product.Id, product, (id, value) => product); await tx.CommitAsync(); } }
public async Task AddProduct(Product product) { IReliableDictionary <Guid, Product> products = await _stateManager.GetOrAddAsync <IReliableDictionary <Guid, Product> >("products"); using (ITransaction tx = _stateManager.CreateTransaction()) { await products.AddOrUpdateAsync(tx, product.Id, product, (id, value) => product); await tx.CommitAsync(); } }
/// <summary> /// Update key value pair in state. /// </summary> /// <param name="key">Key</param> /// <param name="value">Value</param> /// <param name="name">Name</param> /// <returns>bool</returns> internal async Task UpsertKeyValuePairInState(string key, string value, string name) { IReliableDictionary <string, string> votesDictionary = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, string> >(name); using (ITransaction tx = this.stateManager.CreateTransaction()) { await votesDictionary.AddOrUpdateAsync(tx, key, value, (oldKey, oldValue) => value); await tx.CommitAsync(); } }
private async Task UpdateBuildStatus(string name, string status) { IReliableDictionary <string, string> buildsDictionary = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, string> >("builds"); using (ITransaction tx = this.stateManager.CreateTransaction()) { string timestampStatus = $"{DateTime.UtcNow}: {status}"; await buildsDictionary.AddOrUpdateAsync(tx, name, timestampStatus, (key, oldvalue) => timestampStatus); await tx.CommitAsync(); } }
protected override async Task RunAsync(CancellationToken cancellationToken) { cancellationToken.Register(() => this._webApiCancellationSource.Cancel()); IReliableDictionary <string, RateAggregation> citiesDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, RateAggregation> >(RateCitiesDictionaryName); IReliableQueue <RateRequest> queue = await this.StateManager.GetOrAddAsync <IReliableQueue <RateRequest> >(RateQueueName); while (true) { cancellationToken.ThrowIfCancellationRequested(); try { using (var tx = this.StateManager.CreateTransaction()) { var result = await queue.TryDequeueAsync(tx); if (result.HasValue) { RateRequest request = result.Value; // TODO: Process the request // TODO: Go against the reservation provider to pick up the rate // TODO: Determine the reservation provider per tenant from the configuration parameters string providerName = GetParameterValue(ParamatersSection, "ProviderName"); int nights = (request.CheckOutDate - request.CheckInDate).Days; int netAmount = _random.Next(500) * nights; var newAggregation = new RateAggregation(); newAggregation.Transactions = 1; newAggregation.Nights = nights; newAggregation.Amount = (double)netAmount; await citiesDictionary.AddOrUpdateAsync(tx, $"{request.City}/{request.Country}/{providerName}", newAggregation, (key, currentValue) => { currentValue.Transactions += newAggregation.Transactions; currentValue.Nights += newAggregation.Nights; currentValue.Amount += newAggregation.Amount; return(currentValue); }); // This commits the add to dictionary and the dequeue operation. await tx.CommitAsync(); } } } catch (Exception e) { } await Task.Delay(TimeSpan.FromMilliseconds(500), cancellationToken); } }
// NEW public async Task <int> AddVote(string voteItem) { ServiceEventSource.Current.ServiceMessage(this.Context, "VotingDataService.AddVote start. voteItem='{0}'", voteItem); int result = 0; long result2 = 0; using (ITransaction tx = StateManager.CreateTransaction()) { result = await voteDictionary.AddOrUpdateAsync(tx, voteItem, 1, (key, value) => ++ value); result2 = await ballotDictionary.AddOrUpdateAsync(tx, BALLOTS_CAST_KEY, 1, (key, value) => ++ value); //Uncomment to introduce a dodgy bug //if (!string.IsNullOrEmpty(voteItem) && voteItem.ToUpper().StartsWith("TRUMP")) await voteDictionary.AddOrUpdateAsync(tx, voteItem, 1, (key, value) => value += 10); await tx.CommitAsync(); } ServiceEventSource.Current.ServiceMessage(this.Context, "VotingDataService.AddVote end. Total votes: {0}", result.ToString()); return(result); }
private async Task <bool> BackupCallbackAsync(BackupInfo backupInfo) { string backupId = Guid.NewGuid().ToString(); long totalBackupCount; IReliableDictionary <int, long> countDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <int, long> >(this.countDictionaryName); using (ITransaction txn = this.StateManager.CreateTransaction()) { long count = await countDictionary.AddOrUpdateAsync(txn, 0, 0, (key, oldValue) => { return(oldValue + 1); }); totalBackupCount = count; await txn.CommitAsync(); } ServiceEventSource.Current.ServiceMessage(this, "Backup count dictionary updated: " + totalBackupCount); ServiceEventSource.Current.Message("Backup count dictionary updated: " + totalBackupCount); if ((totalBackupCount % 20) == 0) { //The following limits the number of backups stored to 20 per partition. The actual max might be more than 20 per partition since more backups //could have been created when deletion was taking place. //Also depending on the backup that was restored, the count of backups could be a lot larger. this.DeleteBackups(Path.Combine(this.localBackupStore, this.ServicePartition.PartitionInfo.Id.ToString()), 5); } //Simulate a restore/data loss event randomly. This assumes that all partitions have some state at this point. //Five inventory items must be added for all five partitions to have state. if ((totalBackupCount > 19) && (DateTime.Now.Second % 20) == 0) { CancellationToken cancellationToken = default(CancellationToken); ServiceEventSource.Current.ServiceMessage(this, "Restore Started"); using (FabricClient fabricClient = new FabricClient()) { PartitionSelector partitionSelector = PartitionSelector.PartitionIdOf( this.ServiceInitializationParameters.ServiceName, this.ServiceInitializationParameters.PartitionId); await fabricClient.ServiceManager.InvokeDataLossAsync(partitionSelector, DataLossMode.PartialDataLoss, cancellationToken); } } await this.CopyBackupFolderAsync(backupInfo.Directory, this.ServicePartition.PartitionInfo.Id.ToString(), backupId, CancellationToken.None); return(true); }
private async Task<bool> registerResourcesToWatchdog(CancellationToken cancellationToken) { try { var listResources = await StateManagerHelper.GetExternalResourcesAsync(this.StateManager); var updateResources = listResources.Where(p => p.IsUpdate).ToList(); List<Task> listTaskRegister = new List<Task>(); for (int i = 0; i < updateResources.Count; i++) { var rs = listResources[i]; listTaskRegister.Add(new Task(async () => { IReliableDictionary<string, ExternalResource> rsDict = await StateManagerHelper.GetExternalResourceDictAsync(this.StateManager); try { await WatchdogHelper.RegisterHealthCheckAsync(rs.RowKey, this.Context.ServiceName, this.Context.PartitionId, rs.Frequency, $"api/health/{rs.RowKey}", cancellationToken); rs.IsUpdate = false; using (ITransaction tx = this.StateManager.CreateTransaction()) { await rsDict.AddOrUpdateAsync(tx, rs.RowKey, rs, (k, v) => { return rs; }, TimeSpan.FromSeconds(5), CancellationToken.None); await tx.CommitAsync().ConfigureAwait(false); } } catch (Exception ex) { ServiceEventSource.Current.Exception($"Resource {rs.RowKey} register failed", ex.Message, ex.StackTrace); } })); } listTaskRegister.ForEach(task => { task.Start(); }); Task.WaitAll(listTaskRegister.ToArray()); return true; } catch (Exception ex) { ServiceEventSource.Current.Exception("Register resources failed", ex.Message, ex.StackTrace); return false; } }
public async Task <IActionResult> Put([FromBody] UserData user) { IReliableDictionary <string, UserData> usersDict = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, UserData> >(USERS); using (ITransaction tx = this.stateManager.CreateTransaction()) { await usersDict.AddOrUpdateAsync(tx, user.Id, user, (key, oldvalue) => user); await tx.CommitAsync(); } return(this.Json(user)); }
async Task<OperationResult> Process(TestStateful msg, IOperationContext arg2) { using (var trans = _stateManager.CreateTransaction()) { _state = await _stateManager.GetOrAddAsync<IReliableDictionary<string, DateTime>>(ActorRef.Key.Id); await _state.AddOrUpdateAsync(trans, ActorRef.Key.Id, (x) => DateTime.UtcNow, (x, _) => DateTime.UtcNow); await trans.CommitAsync(); } return OperationResult.Success; }