public async Task ConfigureApplication(string application, List <PolicyStorageEntity> policyDetails, ClusterDetails primaryCluster, ClusterDetails secondaryCluster)
        {
            IPolicyStorageService policyStorageClient = ServiceProxy.Create <IPolicyStorageService>(new Uri("fabric:/SFAppDRTool/PolicyStorageService"));
            bool overwritePolicyDetails = false;
            bool stored = policyStorageClient.PostStorageDetails(policyDetails, primaryCluster.httpEndpoint, primaryCluster.certificateThumbprint, overwritePolicyDetails).GetAwaiter().GetResult();

            await MapPartitionsOfApplication(new Uri(application), primaryCluster, secondaryCluster, "partitionDictionary");

            IReliableDictionary <String, List <String> > configuredApplicationsDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, List <String> > >("configuredApplicationsDictionary");

            using (var tx = this.StateManager.CreateTransaction())
            {
                String primarySecondaryJoin = Utility.getPrimarySecondaryClusterJoin(primaryCluster.address, secondaryCluster.address);
                ConditionalValue <List <String> > applicationsList = await configuredApplicationsDictionary.TryGetValueAsync(tx, primarySecondaryJoin);

                if (applicationsList.HasValue)
                {
                    List <String> configuredApplicationsList = applicationsList.Value;
                    configuredApplicationsList.Add(application);
                    var result = await configuredApplicationsDictionary.TryAddAsync(tx, primarySecondaryJoin, configuredApplicationsList);
                }
                else
                {
                    List <String> configuredApplicationsList = new List <String>();
                    configuredApplicationsList.Add(application);
                    var result = await configuredApplicationsDictionary.TryAddAsync(tx, primarySecondaryJoin, configuredApplicationsList);
                }

                await tx.CommitAsync();
            }
        }
        public async Task <T> NewMessage <T>(IdempotentMessage <T> message)
        {
            DateTimeOffset now = DateTimeOffset.Now;

            if ((now - lastClear).TotalSeconds > 1.5 * maxDelaySeconds)
            {
                await Clear();
            }
            if ((now - message.Time).TotalSeconds > maxDelaySeconds)
            {
                return(default(T));
            }
            using (ITransaction tx = this.sm.CreateTransaction())
            {
                var result = await dictionary.TryGetValueAsync(tx, message.Id);

                if (result.HasValue)
                {
                    tx.Abort();
                    return(default(T));
                }
                else
                {
                    await dictionary.TryAddAsync(tx, message.Id, message.Time);

                    await tx.CommitAsync();

                    return(message.Value);
                }
            }
        }
        public async Task <bool> TryAddAsync(ITransaction tx, TKey key, TValue value)
        {
            if (reliableDictionary == null)
            {
                await InitializeReliableDictionary();
            }

            return(await reliableDictionary.TryAddAsync(tx, key, value));
        }
Exemple #4
0
        // Maps named partitions based on their name
        public async Task MapNamedPartitions(Uri applicationName, Uri serviceName, ClusterDetails primaryCluster, ServicePartitionList primaryPartitions, ClusterDetails secondaryCluster, ServicePartitionList secondaryPartitions, string reliableDictionary)
        {
            IReliableDictionary <Guid, PartitionWrapper> myDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, PartitionWrapper> >(reliableDictionary);

            foreach (var primaryPartition in primaryPartitions)
            {
                var partitionNamePrimary = (primaryPartition.PartitionInformation as NamedPartitionInformation).Name;
                foreach (var secondaryPartition in secondaryPartitions)
                {
                    string partitionNameSecondary = (secondaryPartition.PartitionInformation as NamedPartitionInformation).Name;
                    if (partitionNamePrimary == partitionNameSecondary)
                    {
                        using (var tx = this.StateManager.CreateTransaction())
                        {
                            var result = await myDictionary.TryAddAsync(tx, primaryPartition.PartitionInformation.Id, new PartitionWrapper(secondaryPartition, primaryPartition.PartitionInformation.Id, applicationName, serviceName, primaryCluster, secondaryCluster));

                            ServiceEventSource.Current.ServiceMessage(this.Context, result ? "Successfully Mapped Partition-{0} to Partition-{1}" : "Already Exists", primaryPartition.PartitionInformation.Id, secondaryPartition.PartitionInformation.Id);
                            // 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();
                        }
                    }
                }
            }
        }
Exemple #5
0
        /// <summary>
        ///     Register
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task <UserRegisterRequestModel> Register(UserRegisterRequestModel request)
        {
            IReliableDictionary <string, UserState> myDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, UserState> >("Users");

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue <UserState> result = await myDictionary.TryGetValueAsync(tx, request.CellPhone);

                if (!result.HasValue)
                {
                    UserState state = new UserState
                    {
                        CellPhone      = request.CellPhone,
                        PassWord       = request.PassWord,
                        RealName       = request.RealName,
                        UserIdentifier = Guid.NewGuid()
                    };
                    bool isSuc = await myDictionary.TryAddAsync(tx, state.CellPhone, state);

                    await tx.CommitAsync();

                    if (!isSuc)
                    {
                        return(null);
                    }
                    request.UserIdentifier = state.UserIdentifier;
                    return(request);
                }
                request.UserIdentifier = result.Value.UserIdentifier;
                return(request);
            }
        }
        /// <summary>
        /// Saves a HealthCheckScheduleItem to the dictionary.
        /// </summary>
        /// <param name="tx">ITransaction instance.</param>
        /// <param name="item">HealthCheckScheuleItem instance.</param>
        /// <returns>True if successful, otherwise false.</returns>
        /// <remarks>Separate method to address possible key collisions.</remarks>
        internal async Task <bool> SaveAsync(ITransaction tx, WatchdogScheduledItem item)
        {
            int retryCount = 5;

            // Get the schedule dictionary.
            IReliableDictionary <long, WatchdogScheduledItem> schedDict = await this.GetHealthCheckScheduleDictionaryAsync().ConfigureAwait(false);

            // Get a copy of the desired execution time.
            long key = item.ExecutionTicks;

            while (retryCount-- >= 0)
            {
                // Attempt to add the item. There may be a collision because the key already exists.
                // If it doesn't succeed try again with a new key.
                if (await schedDict.TryAddAsync(tx, key, item, this._timeout, this._token).ConfigureAwait(false))
                {
                    return(true);
                }

                // Increment the key value.
                key++;
            }

            // Exhausted the number of allowed retries.
            return(false);
        }
Exemple #7
0
        // Maps Int64 partitions based on their low key
        public async Task MapInt64Partitions(Uri applicationName, Uri serviceName, ClusterDetails primaryCluster, ServicePartitionList primaryPartitions, ClusterDetails secondaryCluster, ServicePartitionList secondaryPartitions, string reliableDictionary)
        {
            IReliableDictionary <Guid, PartitionWrapper> myDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, PartitionWrapper> >(reliableDictionary);

            foreach (var primaryPartition in primaryPartitions)
            {
                long hashCode = HashUtil.getLongHashCode(primaryPartition.PartitionInformation.Id.ToString());
                if (await BelongsToPartition(hashCode))
                {
                    var  int64PartitionInfo = primaryPartition.PartitionInformation as Int64RangePartitionInformation;
                    long?lowKeyPrimary      = int64PartitionInfo?.LowKey;
                    foreach (var secondaryPartition in secondaryPartitions)
                    {
                        long?lowKeySecondary = (secondaryPartition.PartitionInformation as Int64RangePartitionInformation)?.LowKey;
                        if (lowKeyPrimary == lowKeySecondary)
                        {
                            using (var tx = this.StateManager.CreateTransaction())
                            {
                                var result = await myDictionary.TryAddAsync(tx, primaryPartition.PartitionInformation.Id, new PartitionWrapper(secondaryPartition, primaryPartition.PartitionInformation.Id, applicationName, serviceName, primaryCluster, secondaryCluster));

                                ServiceEventSource.Current.ServiceMessage(this.Context, result ? "Successfully Mapped Partition-{0} to Partition-{1}" : "Already Exists", primaryPartition.PartitionInformation.Id, secondaryPartition.PartitionInformation.Id);
                                await tx.CommitAsync();
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// This is called by Restore Service to and it stores the storage details along with the policy details in the reliable dictionary
        /// </summary>
        /// <param name="policies"></param>
        /// <param name="primaryClusterConnectionString"></param>
        /// <returns></returns>
        public async Task <bool> PostStorageDetails(List <PolicyStorageEntity> policies, string primaryClusterConnectionString)
        {
            IReliableDictionary <string, BackupStorage> myDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, BackupStorage> >("storageDictionary");

            foreach (var entity in policies)
            {
                BackupStorage backupStorage = await GetStorageInfo(entity.policy, primaryClusterConnectionString);

                if (backupStorage != null && entity.backupStorage != null)
                {
                    backupStorage.connectionString  = entity.backupStorage.connectionString;
                    backupStorage.primaryUsername   = entity.backupStorage.primaryUsername;
                    backupStorage.primaryPassword   = entity.backupStorage.primaryPassword;
                    backupStorage.secondaryUsername = entity.backupStorage.secondaryUsername;
                    backupStorage.secondaryPassword = entity.backupStorage.secondaryPassword;
                    backupStorage.friendlyname      = entity.backupStorage.friendlyname;
                }
                else
                {
                    return(false);
                }
                using (var tx = this.StateManager.CreateTransaction())
                {
                    var result = await myDictionary.TryAddAsync(tx, entity.policy, backupStorage);

                    ServiceEventSource.Current.ServiceMessage(this.Context, result ? "Successfully added policy {0} storgae details" : "Already Exists", entity.policy);

                    // 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();
                }
            }
            return(true);
        }
        public async Task <T> Add(T entity)
        {
            var storableEntity = _mapper.MapToStorable(entity);
            var succeed        = await _aggreateStorage.TryAddAsync(_transaction, entity.Id, storableEntity);

            if (!succeed)
            {
                throw new Exception("Something went wrong when trying to add the turn");
            }
            return(entity);
        }
Exemple #10
0
        /// <summary>
        /// This is called by Restore Service to and it stores the storage details along with the policy details in the reliable dictionary
        /// </summary>
        /// <param name="policies"></param>
        /// <param name="primaryClusterConnectionString"></param>
        /// <returns></returns>
        public async Task <bool> PostStorageDetails(List <PolicyStorageEntity> policies, string primaryClusterConnectionString, string clusterThumbprint, bool overwritePolicyDetails)
        {
            IReliableDictionary <string, BackupStorage> myDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, BackupStorage> >("storageDictionary");

            foreach (var entity in policies)
            {
                BackupStorage backupStorage;
                try
                {
                    backupStorage = await GetStorageInfo(entity.policy, primaryClusterConnectionString, clusterThumbprint);
                }
                catch (Exception ex) {
                    ServiceEventSource.Current.Message("Policy Storage Service: Exception getting storage info {0}", ex);
                    throw;
                }
                if (backupStorage != null && entity.backupStorage != null)
                {
                    backupStorage.connectionString  = entity.backupStorage.connectionString;
                    backupStorage.primaryUsername   = entity.backupStorage.primaryUsername;
                    backupStorage.primaryPassword   = entity.backupStorage.primaryPassword;
                    backupStorage.secondaryUsername = entity.backupStorage.secondaryUsername;
                    backupStorage.secondaryPassword = entity.backupStorage.secondaryPassword;
                    backupStorage.friendlyname      = entity.backupStorage.friendlyname;
                    backupStorage.Encrypt();
                }
                else
                {
                    return(false);
                }
                using (var tx = this.StateManager.CreateTransaction())
                {
                    ConditionalValue <BackupStorage> cndbackupStorage = await myDictionary.TryGetValueAsync(tx, entity.policy);

                    if (!cndbackupStorage.HasValue || cndbackupStorage.HasValue && overwritePolicyDetails)
                    {
                        var result = await myDictionary.TryAddAsync(tx, entity.policy, backupStorage);

                        ServiceEventSource.Current.ServiceMessage(this.Context, result ? "Successfully added policy {0} storage details" : "Could not add policy", entity.policy);
                    }
                    else
                    {
                        ServiceEventSource.Current.ServiceMessage(this.Context, "Policy {0} already exists", entity.policy);
                    }

                    // 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();
                }
            }
            return(true);
        }
        // Maps singleton partitions
        public async Task MapSingletonPartition(Uri applicationName, Uri serviceName, ClusterDetails primaryCluster, ServicePartitionList primaryPartitions, ClusterDetails secondaryCluster, ServicePartitionList secondaryPartitions, string partitionDictionaryName)
        {
            IReliableDictionary <String, PartitionWrapper> partitionDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, PartitionWrapper> >(partitionDictionaryName);

            using (var tx = this.StateManager.CreateTransaction())
            {
                var result = await partitionDictionary.TryAddAsync(tx, Utility.getPartitionAccessKey(primaryPartitions[0].PartitionInformation.Id, primaryCluster.address, secondaryCluster.address), new PartitionWrapper(secondaryPartitions[0], primaryPartitions[0].PartitionInformation.Id, applicationName, serviceName, primaryCluster, secondaryCluster));

                ServiceEventSource.Current.ServiceMessage(this.Context, result ? "Successfully Mapped Partition-{0} to Partition-{1}" : "Already Exists", primaryPartitions[0].PartitionInformation.Id, secondaryPartitions[0].PartitionInformation.Id);
                // 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();
            }
        }
Exemple #12
0
        public async Task PostStorageDetails(string backupPolicy, BackupStorage backupStorage)
        {
            IReliableDictionary <string, BackupStorage> myDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, BackupStorage> >("storageDictionary");

            using (var tx = this.StateManager.CreateTransaction())
            {
                var result = await myDictionary.TryAddAsync(tx, backupPolicy, backupStorage);

                ServiceEventSource.Current.ServiceMessage(this.Context, result ? "Successfully added policy {0} storgae details" : "Already Exists", backupPolicy);

                // 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();
            }
        }
        /// <summary>
        ///     Registers the configuration.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public async Task <bool> RegisterConfiguration(ConsumerConfigureRequestModel request)
        {
            IReliableDictionary <string, ConsumerConfiguresState> dictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <string, ConsumerConfiguresState> >(DictionaryKey);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue <ConsumerConfiguresState> result = await dictionary.TryGetValueAsync(tx, ConfigureKey);

                bool isSuc;
                if (result.HasValue)
                {
                    int count = result.Value.Configures.Count(x => x.Action.Equals(request.Action) && x.ServiceName.Equals(request.ServiceName) && x.DictionaryKey.Equals(request.DictionaryKey));
                    if (count > 0)
                    {
                        return(false);
                    }
                    ConsumerConfiguresState configure = result.Value;
                    configure.Configures.Add(new ConsumerConfigureInfo
                    {
                        Action        = request.Action,
                        Address       = request.Address,
                        ServiceName   = request.ServiceName,
                        DictionaryKey = request.DictionaryKey
                    });
                    isSuc = await dictionary.TryUpdateAsync(tx, ConfigureKey, configure, result.Value);

                    return(isSuc);
                }
                ConsumerConfiguresState state = new ConsumerConfiguresState
                {
                    Configures = new List <ConsumerConfigureInfo>
                    {
                        new ConsumerConfigureInfo
                        {
                            Action        = request.Action,
                            Address       = request.Address,
                            ServiceName   = request.ServiceName,
                            DictionaryKey = request.DictionaryKey
                        }
                    }
                };
                isSuc = await dictionary.TryAddAsync(tx, ConfigureKey, state);

                await tx.CommitAsync();

                return(isSuc);
            }
        }
        private async Task <string> AddUserAsync(string user)
        {
            IReliableDictionary <String, String> dictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, String> >("dictionary");

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                bool addResult = await dictionary.TryAddAsync(tx, user.ToUpperInvariant(), user);

                await tx.CommitAsync();

                return(String.Format(
                           "User {0} {1}",
                           user,
                           addResult ? "sucessfully added" : "already exists"));
            }
        }
Exemple #15
0
        private async Task <string> AddItemToCacheAsync(string collection, string key, string data)
        {
            IReliableDictionary <String, String> dictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, String> >(collection);

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                bool addResult = await dictionary.TryAddAsync(tx, key.ToUpperInvariant(), data);

                await tx.CommitAsync();

                return(String.Format(
                           "Type '{0}', Item '{1}' {2}",
                           collection,
                           key,
                           addResult ? "sucessfully added" : "already exists"));
            }
        }
Exemple #16
0
        private async Task <RCAddResult> AddInstallerPackageAsync(InstallerPkg pkg)
        {
            IReliableDictionary <string, InstallerPkg> packagesDictionary = await this._statemanager.GetOrAddAsync <IReliableDictionary <string, InstallerPkg> >("packages");

            using (ITransaction tx = _statemanager.CreateTransaction())
            {
                var result = await packagesDictionary.TryGetValueAsync(tx, pkg.Name);

                if (result.HasValue)
                {
                    return(RCAddResult.KeyAlreadyExists);
                }

                if (!await packagesDictionary.TryAddAsync(tx, pkg.Name, pkg))
                {
                    return(RCAddResult.Failure);
                }

                await tx.CommitAsync();
            }

            return(RCAddResult.Success);
        }
        /// <summary>
        /// Performs a HealthCheck for a scheduled item.
        /// </summary>
        /// <param name="item">WatchdogScheduledItem instance.</param>
        internal async Task PerformItemHealthCheckAsync(WatchdogScheduledItem item)
        {
            // Get the health check dictionaries.
            IReliableDictionary <string, HealthCheck> dict = await this.GetHealthCheckDictionaryAsync();

            IReliableDictionary <long, WatchdogScheduledItem> scheduleDict = await this.GetHealthCheckScheduleDictionaryAsync();

            // Create a transaction.
            using (ITransaction tx = this._service.StateManager.CreateTransaction())
            {
                // Attempt to get the HealthCheck instance for the key. If not return.
                ConditionalValue <HealthCheck> cv = await dict.TryGetValueAsync(tx, item.Key, LockMode.Update);

                if (cv.HasValue)
                {
                    HealthCheck hc = cv.Value;

                    try
                    {
                        // Find the partition information that matches the partition identifier.
                        // If the partition isn't found, remove the health check item.
                        Partition partition = await this.FindMatchingPartitionAsync(hc.Partition);

                        if (null == partition)
                        {
                            await dict.TryRemoveAsync(tx, hc.Key, this._timeout, this._token);
                        }
                        else
                        {
                            // Execute the check and evaluate the results returned in the new HealthCheck instance.
                            hc = await this.ExecuteHealthCheckAsync(hc, partition);

                            // Update the value of the HealthCheck to store the results of the test.
                            await dict.TryUpdateAsync(tx, item.Key, hc, cv.Value);

                            // Remove the current scheduled item.
                            await scheduleDict.TryRemoveAsync(tx, item.ExecutionTicks);

                            // Add the new scheduled item.
                            WatchdogScheduledItem newItem = new WatchdogScheduledItem(hc.LastAttempt.Add(hc.Frequency), hc.Key);
                            await(scheduleDict.TryAddAsync(tx, newItem.ExecutionTicks, newItem));
                        }

                        // Commit the transaction.
                        await tx.CommitAsync();
                    }
                    catch (TimeoutException ex)
                    {
                        ServiceEventSource.Current.ServiceMessage(this._service.Context, ex.Message);
                    }
                    catch (FabricNotPrimaryException ex)
                    {
                        ServiceEventSource.Current.ServiceMessage(this._service.Context, ex.Message);
                        return;
                    }
                    catch (Exception ex)
                    {
                        ServiceEventSource.Current.ServiceMessage(this._service.Context, ex.Message);
                        throw;
                    }
                }
            }
        }
        // An interface method which is for disconfiguring the appliations thereby deleting their entries in reliable dictionary.
        public async Task <string> DisconfigureApplication(string applicationName, string primaryCluster, string secondaryCluster)
        {
            List <String> keysToRemove = new List <String>();
            IReliableDictionary <String, PartitionWrapper> myDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, PartitionWrapper> >("partitionDictionary");

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                IAsyncEnumerable <KeyValuePair <String, PartitionWrapper> > enumerable = await myDictionary.CreateEnumerableAsync(tx);

                IAsyncEnumerator <KeyValuePair <String, PartitionWrapper> > asyncEnumerator = enumerable.GetAsyncEnumerator();
                while (await asyncEnumerator.MoveNextAsync(CancellationToken.None))
                {
                    PartitionWrapper secondaryPartition = asyncEnumerator.Current.Value;
                    String           partitionAccessKey = asyncEnumerator.Current.Key;

                    if (Utility.isPartitionFromPrimarySecondaryCombination(partitionAccessKey, primaryCluster, secondaryCluster))
                    {
                        if (secondaryPartition.applicationName.ToString().Equals(applicationName))
                        {
                            keysToRemove.Add(asyncEnumerator.Current.Key);
                        }
                    }
                }
                await tx.CommitAsync();
            }
            bool allPartitionsRemoved = true;

            using (ITransaction tx = this.StateManager.CreateTransaction())
            {
                foreach (String key in keysToRemove)
                {
                    ConditionalValue <PartitionWrapper> value = myDictionary.TryRemoveAsync(tx, key).Result;
                    if (!value.HasValue)
                    {
                        allPartitionsRemoved = false;
                    }
                }
                await tx.CommitAsync();
            }

            IReliableDictionary <String, List <String> > configuredApplicationsDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, List <String> > >("configuredApplicationsDictionary");

            using (var tx = this.StateManager.CreateTransaction())
            {
                String primarySecondaryJoin = Utility.getPrimarySecondaryClusterJoin(primaryCluster, secondaryCluster);
                ConditionalValue <List <String> > applicationsList = await configuredApplicationsDictionary.TryGetValueAsync(tx, primarySecondaryJoin);

                if (applicationsList.HasValue)
                {
                    List <String> configuredApplicationsList = applicationsList.Value;
                    configuredApplicationsList.Remove(applicationName);
                    var result = await configuredApplicationsDictionary.TryAddAsync(tx, primarySecondaryJoin, configuredApplicationsList);
                }
                await tx.CommitAsync();
            }

            if (allPartitionsRemoved)
            {
                return(applicationName);
            }
            return(null);
        }
Exemple #19
0
        private async Task <bool> MatchmakeOneGame(CancellationToken cancellationToken, IReliableConcurrentQueue <UserRequest> queue, IReliableDictionary <ActorInfo, PlayersInMatch> usedActors, IReliableDictionary <UserRequest, ActorInfo> matchmakedUsers)
        {
            try
            {
                ConditionalValue <UserRequest> ret;
                PlayersInMatch players = new PlayersInMatch();
                ActorInfo      actorId;

                using (var tx = this.StateManager.CreateTransaction())
                {
                    do
                    {
                        ret = await queue.TryDequeueAsync(tx, cancellationToken);

                        if (ret.HasValue)
                        {
                            players = players.AddPlayer(new UserRequest(ret.Value));
                        }
                    }while (!cancellationToken.IsCancellationRequested && ret.HasValue && players.Count < MatchSize);

                    if (cancellationToken.IsCancellationRequested || players.Count != MatchSize)
                    {
                        ServiceEventSource.Current.ServiceMessage(this.Context, cancellationToken.IsCancellationRequested ? $"Cancellation requested!" : $"Not enough players in the queue to matchmake!");
                        tx.Abort();
                        return(false);
                    }

                    // found enough players - assign them actor
                    //bool usedActor = false;
                    //do
                    //{
                    //    actorId = ActorId.CreateRandom();
                    //    usedActor = await usedActors.ContainsKeyAsync(tx, actorId);
                    //}
                    //while (!cancellationToken.IsCancellationRequested && usedActor);

                    actorId = await GetSimulationActorId(tx, cancellationToken);

                    if (cancellationToken.IsCancellationRequested)
                    {
                        ServiceEventSource.Current.ServiceMessage(this.Context, $"Cancellation requested!");
                        tx.Abort();
                        return(false);
                    }

                    bool added = await usedActors.TryAddAsync(tx, actorId, players);

                    if (!added)
                    {
                        ServiceEventSource.Current.ServiceMessage(this.Context, $"Tried to add already used actor {actorId}");
                        tx.Abort();
                        return(false);
                    }

                    var playersToAdd = players.GetList();
                    List <UserRequest> addedPlayers = new List <UserRequest>();

                    foreach (var player in playersToAdd)
                    {
                        added = await matchmakedUsers.TryAddAsync(tx, player, actorId);

                        if (added)
                        {
                            addedPlayers.Add(player);
                        }
                    }

                    if (addedPlayers.Count != playersToAdd.Count)
                    {
                        foreach (var player in addedPlayers)
                        {
                            await matchmakedUsers.TryRemoveAsync(tx, player);

                            await queue.EnqueueAsync(tx, player);
                        }
                        ServiceEventSource.Current.ServiceMessage(this.Context, $"Some duplicated requests encountered");
                    }

                    await tx.CommitAsync();
                }

                List <UserRequest> playersList = players.GetList();

                // Create actor simulation
                int index = actorId.ActorIndex;

                string           suffix          = GetSimulationActorNameSuffix(index);
                string           actorServiceUri = $"{this.context.CodePackageActivationContext.ApplicationName}/SimulationActorService{suffix}";
                ISimulationActor simulationActor = ActorProxy.Create <ISimulationActor>(actorId.ActorId, new Uri(actorServiceUri));

                bool simulated = await simulationActor.SimulateMatch(playersList, actorId);

                if (!simulated)
                {
                    ServiceEventSource.Current.Message($"Something went wrong with simulation");
                    return(false);
                }

                await simulationActor.SubscribeAsync <ISimulationEvents>(this, ResubsriptionInterval);

                // Notify clients
                IWebService webService = ServiceProxy.Create <IWebService>(new Uri($"{this.context.CodePackageActivationContext.ApplicationName}/WebService"));
                await webService.StartGame(actorId, playersList);

                StringBuilder builder = new StringBuilder();
                builder.Append($"Created new match\n ActorID: {actorId}\n");

                for (int i = 0; i < players.Count; i++)
                {
                    builder.Append($"UserID_{i}: {playersList[i]}\n");
                }

                ServiceEventSource.Current.ServiceMessage(this.Context, builder.ToString());

                return(true);
            }
            catch (Exception ex)
            {
                ServiceEventSource.Current.Message(string.Format("Exception {0}", ex));
                return(false);
            }
        }
 public Task <bool> TryAdd(Core.ITransaction tx, TKey key, TValue value)
 {
     return(wrappedReliableDictionary.TryAddAsync(((ServiceFabTransaction)tx).WrappedTransaction, key, value));
 }
Exemple #21
0
 public Task <bool> TryAddAsync(ITransaction tx, TKey key, TimeSpan timeout = default(TimeSpan), CancellationToken cancellationToken = default(CancellationToken))
 => m_dictionary.TryAddAsync(tx, key, null, timeout.DefaultToInfinite(), cancellationToken);