public async Task <IEnumerable <Product> > GetAllProducts()
        {
            var nullableProductDictionary = await reliableStateManager.TryGetAsync <IReliableDictionary <Guid, Product> >("products");

            var result = new List <Product>();

            if (!nullableProductDictionary.HasValue)
            {
                return(result);
            }

            var productDictionary = nullableProductDictionary.Value;

            using (var tx = reliableStateManager.CreateTransaction())
            {
                var enumerator = (await productDictionary.CreateEnumerableAsync(tx)).GetAsyncEnumerator();

                while (await enumerator.MoveNextAsync(CancellationToken.None))
                {
                    result.Add(enumerator.Current.Value);
                }
            }

            return(result);
        }
        public async Task <byte[]> GetCacheItemAsync(string key, string clientId, string tenantId, TimeSpan timeout, CancellationToken cancellationToken)
        {
            var metaDictionary = await _stateManager.TryGetAsync <IReliableDictionary <string, CacheEntry> >(GetMetadataDictionaryName(clientId, tenantId));

            if (!metaDictionary.HasValue)
            {
                return(null);
            }
            var dataDictionary = await _stateManager.TryGetAsync <IReliableDictionary <string, byte[]> >(GetDataDictionaryName(clientId, tenantId));

            if (!dataDictionary.HasValue)
            {
                return(null);
            }
            ConditionalValue <CacheEntry> meta;
            var  data = new ConditionalValue <byte[]>();
            bool isExpired;

            using (var transaction = _stateManager.CreateTransaction())
            {
                meta = await metaDictionary.Value.TryGetValueAsync(transaction, key, LockMode.Default, timeout, cancellationToken);

                if (!meta.HasValue)
                {
                    return(null);
                }
                isExpired = IsExpired(meta.Value);
                if (!isExpired)
                {
                    data = await dataDictionary.Value.TryGetValueAsync(transaction, key, LockMode.Default, timeout, cancellationToken);

                    if (!data.HasValue)
                    {
                        return(null);
                    }
                }
            }

            if (isExpired)
            {
                await DeleteCacheItemAsync(key, clientId, tenantId, timeout, cancellationToken);

                return(null);
            }
            else
            {
                _ = await UpdateLastAccessedAsync(key, meta.Value, metaDictionary.Value, timeout, cancellationToken);

                return(data.Value);
            }
        }
Beispiel #3
0
        public static async Task <IEnumerable <ReliableStateInfo> > GetAllStates(this IReliableStateManager stateManager, CancellationToken ct = default(CancellationToken))
        {
            var states = new List <ReliableStateInfo>();

            using (var tx = stateManager.CreateTransaction())
            {
                var enumerable = stateManager.GetAsyncEnumerator();
                while (await enumerable.MoveNextAsync(ct))
                {
                    var reliableStateInfo = new ReliableStateInfo()
                    {
                        Name  = enumerable.Current.Name.ToString(),
                        Count = -1
                    };

                    var conditionalValue = await stateManager.TryGetAsync <IReliableState>(enumerable.Current.Name);

                    if (conditionalValue.HasValue)
                    {
                        var rsi = await conditionalValue.Value.GetCount(tx);

                        reliableStateInfo.Count = rsi.Count;
                        reliableStateInfo.Type  = rsi.Type;
                    }
                    states.Add(reliableStateInfo);
                }
            }
            return(states);
        }
Beispiel #4
0
        public async Task <IActionResult> Get()
        {
            try
            {
                var result = new List <KeyValuePair <string, BookingAggregates> >();

                var tryGetResult = await _stateManager.TryGetAsync <IReliableDictionary <string, BookingAggregates> >(ValuesDictionaryName);

                if (tryGetResult.HasValue)
                {
                    IReliableDictionary <string, BookingAggregates> dictionary = tryGetResult.Value;

                    using (ITransaction tx = _stateManager.CreateTransaction())
                    {
                        var list = await dictionary.CreateEnumerableAsync(tx);

                        var enumerator = list.GetAsyncEnumerator();

                        while (await enumerator.MoveNextAsync(CancellationToken.None))
                        {
                            result.Add(enumerator.Current);
                        }
                    }
                }
                return(Json(result));
            }
            catch (FabricException)
            {
                return(new ContentResult {
                    StatusCode = 503, Content = "The service was unable to process the request. Please try again."
                });
            }
        }
Beispiel #5
0
        public async Task <ConditionalValue <T> > TryGetAsync <T>(IReliableStateManager stateManager, string name) where T : IReliableState
        {
            int tryCount = 0;

            while (true)
            {
                try
                {
                    return(await stateManager.TryGetAsync <T>(name));
                }
                catch (FabricNotReadableException fnre)
                {
                    if (++tryCount < maxTryCount)
                    {
                        await Task.Delay(1000);

                        //TOOD: log
                        continue;
                    }
                    else
                    {
                        throw fnre;
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Remove an existing <see cref="IReliableIndexedDictionary{TKey, TValue}"/> with the given name, along with its indexes.
        /// The state is permanently removed from storage and all replicas when this transaction commits.
        /// </summary>
        /// <remarks>
        /// The index definitions indicate the indexes that should be created, or which should exist with this reliable collection.  The index definitions should be
        /// consistent when creating/reading/removing reliable collections, and should not be changed after creation.  Doing so can cause the index to become out of sync
        /// with the primary reliable collection, which will cause runtime exceptions.
        /// </remarks>
        public static async Task RemoveIndexedAsync <TKey, TValue>(this IReliableStateManager stateManager, ITransaction tx, string name, TimeSpan timeout, params IIndexDefinition <TKey, TValue>[] indexes)
            where TKey : IComparable <TKey>, IEquatable <TKey>
        {
            var result = await stateManager.TryGetAsync <IReliableDictionary2 <TKey, TValue> >(name).ConfigureAwait(false);

            if (result.HasValue)
            {
                await stateManager.RemoveIndexedAsync(tx, result.Value.Name, timeout, indexes).ConfigureAwait(false);
            }
        }
Beispiel #7
0
        public async Task EnqueueMessageAsync(ITransaction tx, MessageWrapper message)
        {
            var queueResult = await _stateManager.TryGetAsync <IReliableConcurrentQueue <MessageWrapper> >(SubscriptionDetails.QueueName);

            if (!queueResult.HasValue)
            {
                return;
            }

            await queueResult.Value.EnqueueAsync(tx, message);
        }
Beispiel #8
0
        /// <summary>
        /// Attempts to get an existing <see cref="IReliableIndexedDictionary{TKey, TValue}"/> with the given name, along with its indexes.
        /// </summary>
        /// <remarks>
        /// The index definitions indicate the indexes that should be created, or which should exist with this reliable collection.  The index definitions should be
        /// consistent when creating/reading/removing reliable collections, and should not be changed after creation.  Doing so can cause the index to become out of sync
        /// with the primary reliable collection, which will cause runtime exceptions.
        /// </remarks>
        public static async Task <ConditionalValue <IReliableIndexedDictionary <TKey, TValue> > > TryGetAsync <TKey, TValue>(this IReliableStateManager stateManager, Uri name, params IIndexDefinition <TKey, TValue>[] indexes)
            where TKey : IComparable <TKey>, IEquatable <TKey>
        {
            var result = await stateManager.TryGetAsync <IReliableDictionary2 <TKey, TValue> >(name).ConfigureAwait(false);

            if (!result.HasValue)
            {
                return(new ConditionalValue <IReliableIndexedDictionary <TKey, TValue> >());
            }

            return(await stateManager.TryGetIndexedAsync(result.Value, indexes).ConfigureAwait(false));
        }
Beispiel #9
0
        /// <summary>
        /// Try to load the existing reliable collection for this index and cache it.
        /// This is called internally and should not be directly called.
        /// </summary>
        async Task <bool> IIndexDefinition <TKey, TValue> .TryGetIndexAsync(IReliableStateManager stateManager, Uri baseName)
        {
            var indexName = GetIndexName(baseName);
            var result    = await stateManager.TryGetAsync <IReliableDictionary2 <TFilter, TKey[]> >(indexName).ConfigureAwait(false);

            if (!result.HasValue)
            {
                return(false);
            }

            _index = result.Value;
            return(true);
        }
        public async Task <ActionResult <IEnumerable <Statistics> > > Get()
        {
            try
            {
                var statistics = await stateManager.TryGetAsync <IReliableDictionary2 <string, string> >(StatisticsName);

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

                var dictionary = new Dictionary <string, IEnumerable <Statistics> >();
                using (var tx = stateManager.CreateTransaction())
                {
                    var enumerable = await statistics.Value.CreateEnumerableAsync(tx);

                    var asyncEnumerator = enumerable.GetAsyncEnumerator();

                    while (await asyncEnumerator.MoveNextAsync(CancellationToken.None))
                    {
                        dictionary[asyncEnumerator.Current.Key] = JsonConvert.DeserializeObject <IEnumerable <Statistics> >(asyncEnumerator.Current.Value);
                    }

                    await tx.CommitAsync();
                }

                return(Ok(dictionary.SelectMany(p => p.Value).OrderByDescending(s => s.Id?.Date)));
            }
            catch (Exception e)
            {
                var response = Json(new
                {
                    e.Message
                });
                response.StatusCode = 500;
                return(response);
            }
        }
        /// <summary>
        /// Remove an existing <see cref="IReliableIndexedDictionary{TKey, TValue}"/> with the given name, along with its indexes.
        /// The state is permanently removed from storage and all replicas when this transaction commits.
        /// </summary>
        /// <remarks>
        /// The index definitions indicate the indexes that should be created, or which should exist with this reliable collection.  The index definitions should be
        /// consistent when creating/reading/removing reliable collections, and should not be changed after creation.  Doing so can cause the index to become out of sync
        /// with the primary reliable collection, which will cause runtime exceptions.
        /// </remarks>
        public static async Task RemoveIndexedAsync <TKey, TValue>(this IReliableStateManager stateManager, ITransaction tx, Uri name, TimeSpan timeout, params IIndexDefinition <TKey, TValue>[] indexes)
            where TKey : IComparable <TKey>, IEquatable <TKey>
        {
            var state = await stateManager.TryGetAsync <IReliableDictionary2 <TKey, TValue> >(name).ConfigureAwait(false);

            if (state.HasValue)
            {
                await stateManager.RemoveAsync(tx, name, timeout).ConfigureAwait(false);
            }

            // Remove all the indexes.
            Uri baseName = GetBaseIndexUri(name);

            foreach (var index in indexes)
            {
                await index.RemoveIndexAsync(tx, stateManager, baseName, timeout).ConfigureAwait(false);
            }
        }
        public void TestInitialize()
        {
            userDictionaryManager = new MockReliableStateManager();

            IReliableDictionary2 <UserName, Basic.Common.UserProfile> users =
                userDictionaryManager.GetOrAddAsync <IReliableDictionary2 <UserName, Basic.Common.UserProfile> >("users").Result;
            var indexed_users = userDictionaryManager.GetOrAddIndexedAsync <UserName, Basic.Common.UserProfile>("indexed_users",
                                                                                                                FilterableIndex <UserName, Basic.Common.UserProfile, string> .CreateQueryableInstance("Email"),
                                                                                                                FilterableIndex <UserName, Basic.Common.UserProfile, int> .CreateQueryableInstance("Age")).Result;

            for (int i = 0; i < 5; i++)
            {
                using (var tx = userDictionaryManager.CreateTransaction())
                {
                    var user = new Basic.Common.UserProfile
                    {
                        Name = new UserName
                        {
                            First = $"First{i}",
                            Last  = $"Last{i}",
                        },
                        Email   = $"user-{i}@example.com",
                        Age     = 20 + i / 3,
                        Address = new Basic.Common.Address
                        {
                            AddressLine1 = $"1{i} Main St.",
                            City         = "Seattle",
                            State        = "WA",
                            Zipcode      = 98117,
                        },
                    };


                    users.SetAsync(tx, user.Name, user, TimeSpan.FromSeconds(4), new CancellationToken());
                    indexed_users.SetAsync(tx, user.Name, user, TimeSpan.FromSeconds(4), new CancellationToken());
                    tx.CommitAsync();
                }
            }

            Assert.IsTrue(userDictionaryManager.TryGetAsync <IReliableDictionary2 <UserName, Basic.Common.UserProfile> >("users").Result.HasValue);
            Assert.IsTrue(userDictionaryManager.TryGetIndexedAsync <UserName, Basic.Common.UserProfile>("indexed_users",
                                                                                                        FilterableIndex <UserName, Basic.Common.UserProfile, string> .CreateQueryableInstance("Email"),
                                                                                                        FilterableIndex <UserName, Basic.Common.UserProfile, int> .CreateQueryableInstance("Age")).Result.HasValue);
        }
        public async Task <int> GetRoomCountAsync(CancellationToken cancellationToken)
        {
            using (var tx = stateManager.CreateTransaction())
            {
                // queue should contain single element which is room count
                var roomCountQueueOptional = await stateManager.TryGetAsync <IReliableQueue <int> >("roomCount");

                if (!roomCountQueueOptional.HasValue || (await roomCountQueueOptional.Value.GetCountAsync(tx)) == 0)
                {
                    // if queue doesn't exist, that means none of chat rooms were created
                    return(0);
                }

                var it = (await roomCountQueueOptional.Value.CreateEnumerableAsync(tx)).GetAsyncEnumerator();
                await it.MoveNextAsync(cancellationToken);

                return(it.Current);
            }
        }
        public async Task <IActionResult> Get([FromQuery] string dictionaryName, [FromQuery] string keyRecord)
        {
            try
            {
                var result = new List <KeyValuePair <string, string> >();

                var tryGetResult = await _stateManager.TryGetAsync <IReliableDictionary <string, string> >(dictionaryName);

                if (tryGetResult.HasValue)
                {
                    var dictionary = tryGetResult.Value;

                    using (ITransaction tx = _stateManager.CreateTransaction())
                    {
                        var enumerable = await dictionary.CreateEnumerableAsync(tx);

                        var enumerator = enumerable.GetAsyncEnumerator();

                        while (await enumerator.MoveNextAsync(CancellationToken.None))
                        {
                            result.Add(enumerator.Current);
                        }
                    }

                    if (!string.IsNullOrEmpty(keyRecord))
                    {
                        return(Ok(result.Where(p => p.Key == keyRecord).ToList()));
                    }
                }

                return(Ok(result));
            }
            catch (FabricException)
            {
                return(new ContentResult {
                    StatusCode = 503, Content = "The service was unable to process the request. Please try again."
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Beispiel #15
0
        /// <summary>
        /// Get the queryable reliable collection by name.
        /// </summary>
        /// <param name="stateManager">Reliable state manager for the replica.</param>
        /// <param name="reliableStateName">Name of the reliable state.</param>
        /// <returns>The reliable collection that supports querying.</returns>
        private static async Task <IReliableState> GetQueryableState(this IReliableStateManager stateManager, string reliableStateName)
        {
            // Find the reliable state.
            var reliableStateResult = await stateManager.TryGetAsync <IReliableState>(reliableStateName).ConfigureAwait(false);

            if (!reliableStateResult.HasValue)
            {
                throw new ArgumentException($"IReliableState '{reliableStateName}' not found in this state manager.");
            }

            // Verify the state is a reliable dictionary.
            var reliableState = reliableStateResult.Value;

            if (!reliableState.ImplementsGenericType(typeof(IReliableDictionary <,>)))
            {
                throw new ArgumentException($"IReliableState '{reliableStateName}' must be an IReliableDictionary.");
            }

            return(reliableState);
        }
    public async Task Run()
    {
        if (endpointConfiguration == null)
        {
            var message = $"{nameof(EndpointCommunicationListener)} Run() method should be invoked after communication listener has been opened and not before.";

            Logger.Log(message);
            throw new Exception(message);
        }

        var zipcodeVotes = await stateManager.TryGetAsync <IReliableDictionary <Guid, SagaEntry> >("zipcode-votes")
                           .ConfigureAwait(false);

        if (zipcodeVotes.HasValue)
        {
            await zipcodeVotes.Value.ClearAsync()
            .ConfigureAwait(false);
        }

        endpointInstance = await Endpoint.Start(endpointConfiguration)
                           .ConfigureAwait(false);
    }
        /// <summary>
        /// Get the queryable reliable collection by name.
        /// </summary>
        /// <param name="stateManager">Reliable state manager for the replica.</param>
        /// <param name="collection">Name of the reliable collection.</param>
        /// <returns>The reliable collection that supports querying.</returns>
        private static async Task <IReliableState> GetQueryableState(this IReliableStateManager stateManager, HttpContext httpContext, string collection)
        {
            // Find the reliable state.
            var reliableStateResult = await stateManager.TryGetAsync <IReliableState>(collection).ConfigureAwait(false);

            if (!reliableStateResult.HasValue)
            {
                QueryableEventSource.Log.ClientError(httpContext.TraceIdentifier, $"This collection : {collection} does not exist", 400);
                throw new ArgumentException($"IReliableState '{collection}' not found in this state manager.");
            }


            // Verify the state is a reliable dictionary.
            var reliableState = reliableStateResult.Value;

            if (!reliableState.ImplementsGenericType(typeof(IReliableDictionary <,>)))
            {
                QueryableEventSource.Log.ClientError(httpContext.TraceIdentifier, $"Collection must be an IReliableDictionary2 to be queried against", 400);
                throw new ArgumentException($"IReliableState '{collection}' must be an IReliableDictionary.");
            }

            return(reliableState);
        }