示例#1
0
        async Task OnSay(Say msg, IOperationContext context)
        {
            RoomMember member;

            if (RoomMembers.TryGetValue(context.ReplyChannel, out member))
            {
                RoomData room;
                if (Rooms.TryGetValue(member.RoomName, out room))
                {
                    var newEvent = new RoomEvent()
                    {
                        UserName = member.UserName, Text = msg.Text
                    };
                    room.History.Add(newEvent);

                    using (var tx = StateManager.CreateTransaction())
                    {
                        await _roomsState.SetAsync(tx, room.Name, room);

                        await tx.CommitAsync();
                    }

                    room.Members.ForEach(m => m.UserChannel.Send(newEvent));
                }
            }
        }
        public async Task SetAsync(ITransaction tx, TKey key, TValue value)
        {
            if (reliableDictionary == null)
            {
                await InitializeReliableDictionary();
            }

            await reliableDictionary.SetAsync(tx, key, value);
        }
        public async Task <ConditionalValue <IReliableDictionary <TKey, TValue> > > TryCopyToReliableDictionary <TKey, TValue>(Dictionary <TKey, TValue> source, string targetKey, IReliableStateManager stateManager) where TKey : IComparable <TKey>, IEquatable <TKey>
        {
            var conditionalValue = await reliableStateManagerHelper.TryGetAsync <IReliableDictionary <TKey, TValue> >(stateManager, targetKey);

            if (!conditionalValue.HasValue)
            {
                return(new ConditionalValue <IReliableDictionary <TKey, TValue> >(false, null));
            }

            IReliableDictionary <TKey, TValue> reliableDictionary = conditionalValue.Value;

            using (ITransaction tx = stateManager.CreateTransaction())
            {
                await reliableDictionary.ClearAsync();

                var tasks = new List <Task>();

                foreach (var kvp in source)
                {
                    tasks.Add(reliableDictionary.SetAsync(tx, kvp.Key, kvp.Value));
                }

                Task.WaitAll(tasks.ToArray());
                await tx.CommitAsync();
            }

            return(new ConditionalValue <IReliableDictionary <TKey, TValue> >(true, reliableDictionary));
        }
示例#4
0
        public async Task <IActionResult> Post(string distName, [FromBody] DistrictReport distReport)
        {
            try
            {
                IReliableDictionary <string, DistrictReport> distReports =
                    await stateManager.GetOrAddAsync <IReliableDictionary <string, DistrictReport> >(CityReports);

                using (ITransaction tx = this.stateManager.CreateTransaction())
                {
                    await distReports.SetAsync(tx, distName, distReport);

                    await tx.CommitAsync();
                }

                return(this.Ok());
            }
            catch (FabricNotPrimaryException ex)
            {
                return(new ContentResult {
                    StatusCode = 410, Content = "The primary replica has moved. Please re-resolve the service."
                });
            }
            catch (FabricException ex)
            {
                return(new ContentResult {
                    StatusCode = 503, Content = "The service was unable to process the request. Please try again."
                });
            }
        }
        private async Task <Tuple <EventPosition, long> > GetOffsetAndEpochAsync(IReliableDictionary <string, string> offsetDictionary, IReliableDictionary <string, long> epochDictionary)
        {
            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue <string> offsetResult = await offsetDictionary.TryGetValueAsync(tx, "offset", LockMode.Default);

                ConditionalValue <long> epochResult = await epochDictionary.TryGetValueAsync(tx, "epoch", LockMode.Update);

                long newEpoch = epochResult.HasValue
                   ? epochResult.Value + 1
                   : 0;

                // epoch is recorded each time the service fails over or restarts.
                await epochDictionary.SetAsync(tx, "epoch", newEpoch);

                await tx.CommitAsync();

                EventPosition eventPosition;
                if (offsetResult.HasValue)
                {
                    eventPosition = EventPosition.FromOffset(offsetResult.Value);
                }
                else
                {
                    // TODO: make this configurable behaviour
                    eventPosition = EventPosition.FromStart();
                }

                return(new Tuple <EventPosition, long>(eventPosition, newEpoch));
            }
        }
示例#6
0
        /// <summary>
        /// Sets the reference data for the passed in dictionary and id to the passed in data
        /// </summary>
        /// <returns></returns>
        public async Task SetReferenceDataAsync(string dictionaryName, int id, string data)
        {
            if (String.IsNullOrWhiteSpace(dictionaryName))
            {
                throw new ArgumentNullException("dicationaryName");
            }

            if (id < 0)
            {
                throw new ArgumentNullException("id");
            }

            ServiceEventSource.Current.ServiceMessage(this.Context, "Request for dictionary: {0}, id: {1} to be updated to {2}", dictionaryName, id, data);

            IReliableDictionary <int, string> ignitionStateDictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <int, string> >(dictionaryName);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                await ignitionStateDictionary.SetAsync(tx, id, data);

                await tx.CommitAsync();
            }

            ServiceEventSource.Current.ServiceMessage(this.Context, "Reference data update completed for dictionary: {0}, id: {1}, new data: {2}", dictionaryName, id, data);
        }
示例#7
0
        /// <summary>
        /// Removes the given quantity of stock from an in item in the inventory.
        /// </summary>
        /// <param name="request"></param>
        /// <returns>int: Returns the quantity removed from stock.</returns>
        public async Task <int> RemoveStockAsync(InventoryItemId itemId, int quantity, CustomerOrderActorMessageId amId)
        {
            int removed = 0;

            ServiceEventSource.Current.ServiceMessage(this, "inside remove stock {0}|{1}", amId.GetHashCode(), amId.GetHashCode());

            IReliableDictionary <InventoryItemId, InventoryItem> inventoryItems =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <InventoryItemId, InventoryItem> >(InventoryItemDictionaryName);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue <InventoryItem> item = await inventoryItems.TryGetValueAsync(tx, itemId);

                if (item.HasValue)
                {
                    removed = item.Value.RemoveStock(quantity);

                    await inventoryItems.SetAsync(tx, itemId, item.Value);

                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "Removed stock complete. Item: {0}. Removed: {1}. Remaining: {2}",
                        item.Value.Id,
                        removed,
                        item.Value.AvailableStock);

                    await tx.CommitAsync();

                    ServiceEventSource.Current.Message("Inventory Service Changes Committed");
                    ServiceEventSource.Current.Message("Removed {0} of item {1}", removed, itemId);
                }
            }
            return(removed);
        }
示例#8
0
        public async Task GenerateActors(IEnumerable <EventData> ehEvents, ITransaction tx)
        {
            if (ehEvents != null)
            {
                int           batchCount  = 0;
                List <string> tempRecords = new List <string>();

                foreach (var ehEvent in ehEvents)
                {
                    string message = Encoding.UTF8.GetString(ehEvent.Body.Array);
                    ServiceEventSource.Current.ServiceMessage(this.serviceContext, $"Message Received: {message}");
                    string[] districtData = message.Split(',');
                    string   distId       = districtData[2];
                    string   distName     = districtData[0];
                    string   distTemp     = districtData[1];
                    //create actor for each district
                    ActorId         districtId     = new ActorId(distId);
                    var             distData       = new DistrictData(distName, distTemp);
                    IDistrictsActor districtsActor = ActorProxy.Create <IDistrictsActor>(districtId, this.DistrictsActorServiceUri);
                    // districtsActor
                    await districtsActor.ProcessDistData(distData);

                    if (batchCount >= 0)// == 4)
                    {
                        var offset = ehEvent.SystemProperties.Offset;
                        await offsetDictionary.SetAsync(tx, "offset", offset);
                    }
                    batchCount++;
                }
            }
        }
示例#9
0
        /// <summary>
        /// Tries to add the given quantity to the inventory item with the given ID without going over the maximum quantity allowed for an item.
        /// </summary>
        /// <param name="itemId"></param>
        /// <param name="quantity"></param>
        /// <returns>The quantity actually added to the item.</returns>
        public async Task <int> AddStockAsync(InventoryItemId itemId, int quantity)
        {
            IReliableDictionary <InventoryItemId, InventoryItem> inventoryItems =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <InventoryItemId, InventoryItem> >(InventoryItemDictionaryName);

            int quantityAdded = 0;

            ServiceEventSource.Current.ServiceMessage(this, "Received add stock request. Item: {0}. Quantity: {1}.", itemId, quantity);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                // Try to get the InventoryItem for the ID in the request.
                ConditionalValue <InventoryItem> item = await inventoryItems.TryGetValueAsync(tx, itemId);

                // We can only update the stock for InventoryItems in the system - we are not adding new items here.
                if (item.HasValue)
                {
                    quantityAdded = item.Value.AddStock(quantity);
                    await inventoryItems.SetAsync(tx, item.Value.Id, item.Value);
                }

                await tx.CommitAsync();

                ServiceEventSource.Current.ServiceMessage(
                    this,
                    "Add stock complete. Item: {0}. Added: {1}. Total: {2}",
                    item.Value.Id,
                    quantityAdded,
                    item.Value.AvailableStock);
            }
            return(quantityAdded);
        }
        public async Task <IActionResult> Post(string name, [FromBody] ValueViewModel value)
        {
            try
            {
                IReliableDictionary <string, string> dictionary =
                    await this.stateManager.GetOrAddAsync <IReliableDictionary <string, string> >(ValuesDictionaryName);

                using (ITransaction tx = this.stateManager.CreateTransaction())
                {
                    await dictionary.SetAsync(tx, name, value.Value);

                    await tx.CommitAsync();
                }

                return(this.Ok());
            }
            catch (FabricNotPrimaryException)
            {
                return(new ContentResult {
                    StatusCode = 503, Content = "The primary replica has moved. Please re-resolve the service."
                });
            }
            catch (FabricException)
            {
                return(new ContentResult {
                    StatusCode = 503, Content = "The service was unable to process the request. Please try again."
                });
            }
        }
示例#11
0
        public async Task GetAll()
        {
            MockApplicationLifetime  appLifetime  = new MockApplicationLifetime();
            MockReliableStateManager stateManager = new MockReliableStateManager();

            IReliableDictionary <string, DeviceEvent> store =
                await stateManager.GetOrAddAsync <IReliableDictionary <string, DeviceEvent> >(DataService.EventDictionaryName);

            Dictionary <string, DeviceEvent> expected = new Dictionary <string, DeviceEvent>();

            expected.Add("device1", new DeviceEvent(DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(1))));
            expected.Add("device2", new DeviceEvent(DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(2))));


            using (ITransaction tx = stateManager.CreateTransaction())
            {
                foreach (var item in expected)
                {
                    await store.SetAsync(tx, item.Key, item.Value);
                }
            }

            DevicesController target = new DevicesController(stateManager, appLifetime);
            IActionResult     result = await target.GetAsync();

            Assert.True(result is OkObjectResult);

            IEnumerable <dynamic> actual = ((OkObjectResult)result).Value as IEnumerable <dynamic>;

            foreach (dynamic item in actual)
            {
                Assert.Equal <DateTimeOffset>(expected[item.Id].Timestamp, item.Timestamp);
            }
        }
示例#12
0
        public async Task ReportLoadAsync(ITransaction tx, Uri collectionName, IEnumerable <LoadMetric> metrics)
        {
            IReliableDictionary <string, List <LoadMetric> > metricDictionary =
                await this.stateManager.GetOrAddAsync <IReliableDictionary <string, List <LoadMetric> > >(this.metricStoreName);

            await metricDictionary.SetAsync(tx, collectionName.ToString(), metrics.ToList());
        }
示例#13
0
        private async Task BackupSequenceNumberAsync()
        {
            if (_latestSequenceNumber > _backupSequenceNumber)
            {
                try
                {
                    IReliableDictionary <string, string> streamOffsetDictionary =
                        await this.StateManager.GetOrAddAsync <IReliableDictionary <string, string> >(Names.EventHubOffsetDictionaryName);

                    using (ITransaction tx = this.StateManager.CreateTransaction())
                    {
                        await streamOffsetDictionary.SetAsync(tx, Names.HubStreamOffSetKey,
                                                              _latestSequenceNumber.ToString());

                        await tx.CommitAsync();
                    }
                }
                catch (Exception exception)
                {
                    string err = $"RouterService BackupSequenceNumberAsync met exception, event hub partition={_eventHubPartitionId}, " +
                                 $"exception type={exception.GetType().Name}, exception= {exception.Message}, at partition ={Context.PartitionId}.";

                    //ServiceEventSource.Current.CriticalError("RouterService", err);
                }

                var suc = await SaveEventDataSequenceNumberAsync();

                if (suc)
                {
                    _backupSequenceNumber = _latestSequenceNumber;
                }
            }
        }
示例#14
0
        public async Task GetOrAddAsyncTestResultGetSet()
        {
            MetricReliableStateManager target = new MetricReliableStateManager(
                this.GetContext(),
                new JsonReliableStateSerializerResolver(),
                this.GetConfig(),
                new MockReliableStateManager());

            IReliableDictionary <int, string> dictionary = await target.GetOrAddAsync <IReliableDictionary <int, string> >("test://dictionary");

            string expected = "testvalue";

            using (ITransaction tx = target.CreateTransaction())
            {
                await dictionary.SetAsync(tx, 1, expected);

                await tx.CommitAsync();
            }

            using (ITransaction tx = target.CreateTransaction())
            {
                ConditionalValue <string> actual = await dictionary.TryGetValueAsync(tx, 1);

                Assert.AreEqual <string>(expected, actual.Value);
            }
        }
示例#15
0
        internal async Task <bool> TryDequeueAndProcessAsync(CancellationToken cancellationToken)
        {
            IReliableQueue <Guid> queue =
                await this.StateManager.GetOrAddAsync <IReliableQueue <Guid> >(QueueName);

            IReliableDictionary <Guid, ApplicationDeployment> dictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, ApplicationDeployment> >(DictionaryName);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue <Guid> workItem = await queue.TryDequeueAsync(tx, this.transactionTimeout, cancellationToken);

                if (!workItem.HasValue)
                {
                    ServiceEventSource.Current.ServiceMessage(this, "No new application deployment requests.");
                    return(false);
                }

                Guid workItemId = workItem.Value;

                ConditionalValue <ApplicationDeployment> appDeployment =
                    await dictionary.TryGetValueAsync(tx, workItemId, LockMode.Update, this.transactionTimeout, cancellationToken);

                if (!appDeployment.HasValue)
                {
                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "Found queued application deployment request with no associated deployment information. Discarding.");

                    return(true);
                }

                ApplicationDeployment processedDeployment = await this.ProcessApplicationDeployment(appDeployment.Value, cancellationToken);

                if (processedDeployment.Status == ApplicationDeployStatus.Complete ||
                    processedDeployment.Status == ApplicationDeployStatus.Failed)
                {
                    // Remove deployments that completed or failed
                    await dictionary.TryRemoveAsync(tx, workItemId, this.transactionTimeout, cancellationToken);
                }
                else
                {
                    // The deployment hasn't completed or failed, so queue up the next stage of deployment
                    await queue.EnqueueAsync(tx, workItemId, this.transactionTimeout, cancellationToken);

                    // And update the deployment record with the new status
                    await dictionary.SetAsync(tx, workItemId, processedDeployment, this.transactionTimeout, cancellationToken);

                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "Application deployment request successfully processed. Cluster: {0}. Status: {1}",
                        processedDeployment.Cluster,
                        processedDeployment.Status);
                }

                await tx.CommitAsync();
            }

            return(true);
        }
示例#16
0
        /// <summary>
        /// This method executes on the bidder's partition.
        /// Called by web: priority 0
        /// </summary>
        public async Task <Bid[]> PlaceBidAsync(String bidderEmail, String sellerEmail, String itemName, Decimal bidAmount, CancellationToken ct)
        {
            Email _sellerEmail = Email.Parse(sellerEmail);

            using (var tx = CreateTransaction()) {
                Email  _bidderEmail = Email.Parse(bidderEmail);
                ItemId itemId       = ItemId.Parse(_sellerEmail, itemName);

                var cr = await m_users.TryGetValueAsync(tx, _bidderEmail);

                if (!cr.HasValue)
                {
                    throw new InvalidOperationException($"Bidder '{_bidderEmail}' doesn't exist.");
                }

                // Create new User object identical to current with new itemId added to it (if not already in collection [idempotent])
                UserInfo userInfo = cr.Value;
                if (!userInfo.ItemsBidding.Contains(itemId))
                {
                    userInfo = userInfo.AddItemBidding(itemId);
                    await m_users.SetAsync(tx, _bidderEmail, userInfo);

                    await tx.CommitAsync();
                }
                // NOTE: If we fail here, the bidder thinks they're bidding on an item but the
                // item doesn't know about the bidder. If so, the bidder will not see their latest bid.
                // The bidder could bid again (which is why adding the item is idempotent).
            }
            // Tell seller's partition to place a bid
            var proxy = (IInternalOperations) new ServiceOperations(s_partitionEndpointResolver, AuctionServiceNameUri);

            return(await proxy.PlaceBid2Async(bidderEmail, sellerEmail, itemName, bidAmount, ct));
        }
示例#17
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            int retryCount = 0;

            while (!cancellationToken.IsCancellationRequested && retryCount < 5)
            {
                try
                {
                    IReliableDictionary <string, DateTimeOffset> timeDictionary =
                        await this.StateManager.GetOrAddAsync <IReliableDictionary <string, DateTimeOffset> >("TimeTracker");

                    using (ITransaction tx = this.StateManager.CreateTransaction())
                    {
                        ConditionalValue <DateTimeOffset> result = await timeDictionary.TryGetValueAsync(tx, "StartTime");

                        if (!result.HasValue)
                        {
                            await timeDictionary.SetAsync(tx, "StartTime", DateTimeOffset.UtcNow);
                        }

                        await tx.CommitAsync();
                    }

                    return;
                }
                catch (TimeoutException te)
                {
                    // transient error. Retry.
                    retryCount++;
                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "NationalService encountered an exception trying to record start time: TimeoutException in RunAsync: {0}",
                        te.ToString());
                    continue;
                }
                catch (FabricTransientException fte)
                {
                    // transient error. Retry.
                    retryCount++;
                    ServiceEventSource.Current.ServiceMessage(
                        this,
                        "NationalService encountered an exception trying to record start time: FabricTransientException in RunAsync: {0}",
                        fte.ToString());
                    continue;
                }
                catch (FabricNotPrimaryException)
                {
                    // not primary any more, time to quit.
                    return;
                }
                catch (Exception ex)
                {
                    ServiceEventSource.Current.ServiceMessage(this, ex.ToString());
                    throw;
                }
            }
        }
示例#18
0
        private async Task ApplyChanges(ITransaction tx, IReliableDictionary <string, CachedItem> cachedItemStore, IReliableDictionary <string, CacheStoreMetadata> cacheStoreMetadata, LinkedDictionaryItemsChanged linkedDictionaryItemsChanged)
        {
            foreach (var cacheItem in linkedDictionaryItemsChanged.CachedItemsToUpdate)
            {
                await cachedItemStore.SetAsync(tx, cacheItem.Key, cacheItem.Value);
            }

            await cacheStoreMetadata.SetAsync(tx, CacheStoreMetadataKey, linkedDictionaryItemsChanged.CacheStoreMetadata);
        }
示例#19
0
        public async Task JoinClusterAsync(string username, string clusterName)
        {
            if (String.IsNullOrWhiteSpace(username))
            {
                throw new ArgumentNullException("username");
            }

            if (String.IsNullOrWhiteSpace(clusterName))
            {
                throw new ArgumentNullException("clusterName");
            }

            IReliableDictionary <string, Cluster> clusterDictionary =
                await this.reliableStateManager.GetOrAddAsync <IReliableDictionary <string, Cluster> >(ClusterDictionaryName);

            int    userPort;
            string clusterAddress;

            using (ITransaction tx = this.reliableStateManager.CreateTransaction())
            {
                ConditionalResult <Cluster> result = await clusterDictionary.TryGetValueAsync(tx, clusterName, LockMode.Update);

                if (!result.HasValue)
                {
                    throw new KeyNotFoundException();
                }

                Cluster cluster = result.Value;

                // make sure the cluster is ready
                if (cluster.Status != ClusterStatus.Ready)
                {
                    throw new InvalidOperationException(); // need a better exception here
                }

                // make sure the cluster isn't about to be deleted.
                if ((DateTimeOffset.UtcNow - cluster.CreatedOn.ToUniversalTime()) > (this.Config.MaxClusterUptime - TimeSpan.FromMinutes(5)))
                {
                    throw new InvalidOperationException(); // need a better exception here
                }

                userPort       = cluster.Ports.First(port => !cluster.Users.Select(x => x.Port).Contains(port));
                clusterAddress = cluster.Address;

                cluster.Users.Add(new ClusterUser()
                {
                    Name = username, Port = userPort
                });

                await clusterDictionary.SetAsync(tx, clusterName, cluster);

                await tx.CommitAsync();
            }

            // send email to user with cluster info
        }
示例#20
0
        public async Task <IActionResult> NewGame(string roomid, string playerid, string playerdata, string roomtype)
        {
            try
            {
                if (!RoomManager.IsActive)
                {
                    return new ContentResult {
                               StatusCode = 503, Content = "Service is still starting up. Please retry."
                    }
                }
                ;

                Player player = JsonConvert.DeserializeObject <Player>(playerdata);

                //get the general room dictionary
                IReliableDictionary <string, Room> roomdict =
                    await this.stateManager.GetOrAddAsync <IReliableDictionary <string, Room> >(RoomDictionaryName);

                //get or add the active room we will put this player in
                IReliableDictionary <string, ActivePlayer> activeroom =
                    await this.stateManager.GetOrAddAsync <IReliableDictionary <string, ActivePlayer> >(roomid);

                using (ITransaction tx = this.stateManager.CreateTransaction())
                {
                    //Find the room in the room dictionary
                    ConditionalValue <Room> roomOption = await roomdict.TryGetValueAsync(tx, roomid, LockMode.Update);

                    if (!roomOption.HasValue)
                    {
                        //Scenario: Room does not exist yet
                        await roomdict.AddAsync(tx, roomid, new Room(1, roomtype));
                    }
                    else
                    {
                        //Scenario: Room does exist
                        Room newRoom = roomOption.Value;
                        newRoom.NumPlayers++;
                        await roomdict.SetAsync(tx, roomid, newRoom);
                    }

                    //Add the data to that room
                    await activeroom.SetAsync(tx, playerid, new ActivePlayer(player, DateTime.UtcNow));

                    await tx.CommitAsync();
                }

                return(new ContentResult {
                    StatusCode = 200, Content = "Successfully Logged In"
                });
            }
            catch (Exception e)
            {
                return(exceptionHandler(e));
            }
        }
示例#21
0
        private async Task <bool> BackupCallbackAsync(BackupInfo backupInfo, CancellationToken cancellationToken)
        {
            ServiceEventSource.Current.ServiceMessage(Context, "Inside backup callback for replica {0}|{1}", this.Context.PartitionId, this.Context.ReplicaId);
            long totalBackupCount;

            IReliableDictionary <string, long> backupCountDictionary =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <string, long> >(BackupCountDictionaryName);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue <long> value = await backupCountDictionary.TryGetValueAsync(tx, "backupCount");

                if (!value.HasValue)
                {
                    totalBackupCount = 0;
                }
                else
                {
                    totalBackupCount = value.Value;
                }

                await backupCountDictionary.SetAsync(tx, "backupCount", ++totalBackupCount);

                await tx.CommitAsync();
            }

            ServiceEventSource.Current.Message("Backup count dictionary updated, total backup count is {0}", totalBackupCount);

            try
            {
                ServiceEventSource.Current.ServiceMessage(Context, "Archiving backup");
                await this.backupManager.ArchiveBackupAsync(backupInfo, cancellationToken);

                ServiceEventSource.Current.ServiceMessage(Context, "Backup archived");
            }
            catch (Exception e)
            {
                ServiceEventSource.Current.ServiceMessage(Context, "Archive of backup failed: Source: {0} Exception: {1}", backupInfo.Directory, e.Message);
            }

            try
            {
                ServiceEventSource.Current.ServiceMessage(Context, "Deleting backups");
                await this.backupManager.DeleteBackupsAsync(cancellationToken);

                ServiceEventSource.Current.ServiceMessage(Context, "Backups deleted");
            }
            catch (Exception e)
            {
                ServiceEventSource.Current.ServiceMessage(Context, "Delete of backup failed: Exception: {1}", e.Message);
            }

            return(true);
        }
        public async Task SetDataAsync(long key, byte[] data)
        {
            IReliableDictionary <long, byte[]> dictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <long, byte[]> >(this.dictionaryName);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                await dictionary.SetAsync(tx, key, data);

                await tx.CommitAsync();
            }
        }
        /// <summary>
        /// This method saves the description (eventString) and timestamp of the recentmost induced fault as
        /// a ChaosEntry in a Reliable Dictionary
        /// </summary>
        /// <param name="eventString"></param>
        /// <returns>A task to await on</returns>
        private async Task StoreEventAsync(string eventString)
        {
            ServiceEventSource.Current.ServiceMessage(this, "ChaosTest: {0}", eventString);

            IReliableDictionary <string, long> eventCount =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <string, long> >(StringResource.EventCountKey);

            IReliableDictionary <string, DateTime> startTime =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <string, DateTime> >(StringResource.StartTimeKey);

            IReliableDictionary <long, ChaosEntry> savedEvents =
                await this.StateManager.GetOrAddAsync <IReliableDictionary <long, ChaosEntry> >(StringResource.SavedEventsKey);


            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                if (!await startTime.ContainsKeyAsync(tx, StringResource.StartTimeKey))
                {
                    await startTime.AddAsync(tx, StringResource.StartTimeKey, DateTime.UtcNow);
                }

                if (!await eventCount.ContainsKeyAsync(tx, StringResource.EventCountKey))
                {
                    await eventCount.AddAsync(tx, StringResource.EventCountKey, 0);
                }

                ConditionalValue <long> result =
                    await eventCount.TryGetValueAsync(tx, StringResource.EventCountKey, LockMode.Update);

                if (result.HasValue)
                {
                    long currentCount = result.Value;

                    // If we have HistoryLength number of events, we make room for new events by removing oldest ones,
                    // always keeping HistoryLength number of recentmost events on the show on the webpage.
                    if (currentCount > Constants.HistoryLength - 1)
                    {
                        await savedEvents.TryRemoveAsync(tx, currentCount - Constants.HistoryLength + 1);
                    }

                    ChaosEntry chaosEntry = new ChaosEntry
                    {
                        Record    = eventString,
                        TimeStamp = DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)
                    };

                    await savedEvents.AddAsync(tx, ++currentCount, chaosEntry);

                    await eventCount.SetAsync(tx, StringResource.EventCountKey, currentCount);

                    await tx.CommitAsync();
                }
            }
        }
        internal static async Task RemoveSubscription(
            this IReliableDictionary <string, BrokerServiceState> brokerState, ITransaction tx, string queues,
            SubscriptionDetails subscriptionDetails)
        {
            var subscribers = await brokerState.TryGetValueAsync(tx, queues, LockMode.Update);

            if (subscribers.HasValue)
            {
                var newState = BrokerServiceState.RemoveSubscriber(subscribers.Value, subscriptionDetails);
                await brokerState.SetAsync(tx, queues, newState);
            }
        }
示例#25
0
        /// <summary>
        /// Looks for errors in the update tables, and processes one record at a time to create or update corresponding issues.
        /// </summary>
        /// <param name="checkPoint">The last record processed datetime.</param>
        /// <param name="issueRepo">Repository where the gitHub issue has to be created.</param>
        /// <param name="checkpointEvaluator">Reliable dictionary that holds the time the last record was processed.</param>
        /// <returns></returns>
        private async Task CheckForErrorsInUpdateHistoryTablesAsync(
            DateTimeOffset checkPoint,
            string issueRepo,
            IReliableDictionary <string, DateTimeOffset> checkpointEvaluator)
        {
            // First get the un-processed entries from the RepositoryBranchHistory table
            List <UpdateHistoryEntry> unprocessedHistoryEntries =
                _context.RepositoryBranchUpdateHistory
                .Where(entry => entry.Success == false &&
                       entry.Timestamp > checkPoint.UtcDateTime)
                .ToList <UpdateHistoryEntry>();

            // Add in the SubscriptionUpdate errors:
            unprocessedHistoryEntries.AddRange(
                _context.SubscriptionUpdateHistory
                .Where(entry => entry.Success == false &&
                       entry.Timestamp > checkPoint.UtcDateTime));

            // Sort union of these sets by timestamp, so the oldest checkpoint is the oldest unprocessed from both update history tables
            unprocessedHistoryEntries = unprocessedHistoryEntries.OrderBy(entry => entry.Timestamp).ToList();

            if (!unprocessedHistoryEntries.Any())
            {
                _logger.LogInformation($"No errors found in the 'RepositoryBranchUpdates' or 'SubscriptionUpdates' tables. The last checkpoint time was : '{checkPoint}'");
                return;
            }
            foreach (var error in unprocessedHistoryEntries)
            {
                try
                {
                    await IssueDescriptionEvaluator(error, issueRepo);

                    using (ITransaction tx = _stateManager.CreateTransaction())
                    {
                        await checkpointEvaluator.SetAsync(
                            tx,
                            "checkpointEvaluator",
                            error.Timestamp
                            );

                        await tx.CommitAsync();
                    }
                }
                catch (TimeoutException exe)
                {
                    _logger.LogError(exe, $"Unable to update the last processed error timestamp : '{error.Timestamp}");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, $"Unable to create a github issue for error message : '{error.ErrorMessage}' for {GetPrintableDescription(error)}");
                }
            }
        }
示例#26
0
        public async Task <IActionResult> Put(string id, [FromBody] JToken values)
        {
            try
            {
                var userId = values["player"].Value <string>();
                var idx    = values["idx"].Value <int>();

                _logger.Info($"Got move from {userId} for {idx}");

                IReliableDictionary <string, Game> gamesDictionary = await _stateManager.GetOrAddAsync <IReliableDictionary <string, Game> >("games");

                using (ITransaction tx = _stateManager.CreateTransaction())
                {
                    var game = await gamesDictionary.TryGetValueAsync(tx, id);

                    if (!game.HasValue)
                    {
                        return(NotFound());
                    }

                    if (game.Value.State is TicTacToeState state)
                    {
                        _logger.Info("It was a TicTacToeGame");

                        var playerMarker = game.Value.UserRoles[userId];

                        if (state.Board[idx] == null &&
                            ((state.IsXTurn && playerMarker == "X") || (!state.IsXTurn && playerMarker == "O")))
                        {
                            state.Board[idx] = playerMarker;
                            state.IsXTurn    = !state.IsXTurn;

                            await gamesDictionary.SetAsync(tx, id, game.Value);

                            await tx.CommitAsync();
                        }

                        return(Json(state.Board));
                    }
                    else
                    {
                        _logger.Info("It was not a TicTacToeGame");

                        return(BadRequest());
                    }
                }
            }
            catch (Exception e)
            {
                _logger.Info(e.ToString());
                throw;
            }
        }
        public async Task DeleteClusterAsync(string name)
        {
            IReliableDictionary <string, ClusterOperationStatus> clusters =
                await this.stateManager.GetOrAddAsync <IReliableDictionary <string, ClusterOperationStatus> >(new Uri("fakeclusterops:/clusters"));

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                await clusters.SetAsync(tx, name, ClusterOperationStatus.Deleting);

                await tx.CommitAsync();
            }
        }
示例#28
0
        /// <summary>
        /// Adds clusters by the given amount without going over the max threshold and without resulting in below the min threshold.
        /// </summary>
        /// <param name="targetCount"></param>
        /// <returns></returns>
        internal async Task BalanceClustersAsync(int target)
        {
            Random random = new Random();

            IReliableDictionary <int, Cluster> clusterDictionary =
                await this.reliableStateManager.GetOrAddAsync <IReliableDictionary <int, Cluster> >(ClusterDictionaryName);

            using (ITransaction tx = this.reliableStateManager.CreateTransaction())
            {
                var activeClusters     = this.GetActiveClusters(clusterDictionary);
                int activeClusterCount = activeClusters.Count();

                if (target < this.Config.MinimumClusterCount)
                {
                    target = this.Config.MinimumClusterCount;
                }

                if (target > this.Config.MaximumClusterCount)
                {
                    target = this.Config.MaximumClusterCount;
                }

                if (activeClusterCount < target)
                {
                    int limit = Math.Min(target, this.Config.MaximumClusterCount);

                    for (int i = 0; i < limit - activeClusterCount; ++i)
                    {
                        await clusterDictionary.AddAsync(tx, random.Next(), new Cluster());
                    }

                    await tx.CommitAsync();
                }

                if (activeClusterCount > target)
                {
                    var removeList = activeClusters
                                     .Where(x => x.Value.Users.Count == 0)
                                     .Take(Math.Min(activeClusterCount - this.Config.MinimumClusterCount, activeClusterCount - target));

                    foreach (var item in removeList)
                    {
                        Cluster value = item.Value;
                        value.Status = ClusterStatus.Remove;

                        await clusterDictionary.SetAsync(tx, item.Key, value);
                    }

                    await tx.CommitAsync();
                }
            }
        }
示例#29
0
        public async Task <IActionResult> Put(string staff)
        {
            IReliableDictionary <string, int> StaffDictionary = await this.stateManager.GetOrAddAsync <IReliableDictionary <string, int> >("counts");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                await StaffDictionary.SetAsync(tx, staff, 1);

                await tx.CommitAsync();
            }
            telemetry.TrackEvent($"Added a Staff for {staff}");
            return(new OkResult());
        }
示例#30
0
        /// <inheritdocs/>
        public async Task SetChunks(Guid replicaId, IEnumerable <Chunk> chunks)
        {
            var payload = Utils.Serialize(chunks.ToArray());

            await EnsureChunkTables();

            using (var tx = ServiceFabricUtils.CreateTransaction())
            {
                await ServiceFabricUtils.DoWithTimeoutRetry(
                    async() => await m_chunktable.SetAsync(tx, replicaId, payload),
                    async() => await tx.CommitAsync());
            }
        }
        /// <summary>
        /// Creates an EventHubReceiver from the given connection sting and partition key.
        /// The Reliable Dictionaries are used to create a receiver from wherever the service last left off,
        /// or from the current date/time if it's the first time the service is coming up.
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="servicePartitionKey"></param>
        /// <param name="epochDictionary"></param>
        /// <param name="offsetDictionary"></param>
        /// <returns></returns>
        private async Task<Tuple<EventHubReceiver, MessagingFactory>> ConnectToIoTHubAsync(
            string connectionString,
            long servicePartitionKey,
            IReliableDictionary<string, long> epochDictionary,
            IReliableDictionary<string, string> offsetDictionary)
        {

            // EventHubs doesn't support NetMessaging, so ensure the transport type is AMQP.
            ServiceBusConnectionStringBuilder connectionStringBuilder = new ServiceBusConnectionStringBuilder(connectionString);
            connectionStringBuilder.TransportType = TransportType.Amqp;

            ServiceEventSource.Current.ServiceMessage(
                      this.Context,
                      "RouterService connecting to IoT Hub at {0}",
                      String.Join(",", connectionStringBuilder.Endpoints.Select(x => x.ToString())));

            // A new MessagingFactory is created here so that each partition of this service will have its own MessagingFactory.
            // This gives each partition its own dedicated TCP connection to IoT Hub.
            MessagingFactory messagingFactory = MessagingFactory.CreateFromConnectionString(connectionStringBuilder.ToString());
            EventHubClient eventHubClient = messagingFactory.CreateEventHubClient("messages/events");
            EventHubRuntimeInformation eventHubRuntimeInfo = await eventHubClient.GetRuntimeInformationAsync();
            EventHubReceiver eventHubReceiver;

            // Get an IoT Hub partition ID that corresponds to this partition's low key.
            // This assumes that this service has a partition count 'n' that is equal to the IoT Hub partition count and a partition range of 0..n-1.
            // For example, given an IoT Hub with 32 partitions, this service should be created with:
            // partition count = 32
            // partition range = 0..31
            string eventHubPartitionId = eventHubRuntimeInfo.PartitionIds[servicePartitionKey];

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue<string> offsetResult = await offsetDictionary.TryGetValueAsync(tx, "offset", LockMode.Default);
                ConditionalValue<long> epochResult = await epochDictionary.TryGetValueAsync(tx, "epoch", LockMode.Update);

                long newEpoch = epochResult.HasValue
                    ? epochResult.Value + 1
                    : 0;

                if (offsetResult.HasValue)
                {
                    // continue where the service left off before the last failover or restart.
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "Creating EventHub listener on partition {0} with offset {1}",
                        eventHubPartitionId,
                        offsetResult.Value);

                    eventHubReceiver = await eventHubClient.GetDefaultConsumerGroup().CreateReceiverAsync(eventHubPartitionId, offsetResult.Value, newEpoch);
                }
                else
                {
                    // first time this service is running so there is no offset value yet.
                    // start with the current time.
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "Creating EventHub listener on partition {0} with offset {1}",
                        eventHubPartitionId,
                        DateTime.UtcNow);

                    eventHubReceiver =
                        await
                            eventHubClient.GetDefaultConsumerGroup()
                                .CreateReceiverAsync(eventHubPartitionId, DateTime.UtcNow, newEpoch);
                }

                // epoch is recorded each time the service fails over or restarts.
                await epochDictionary.SetAsync(tx, "epoch", newEpoch);
                await tx.CommitAsync();
            }

            return new Tuple<EventHubReceiver, MessagingFactory>(eventHubReceiver, messagingFactory);
        }