public async Task Subscribe(AlgorithmId algorithmId, ResultSubscriptionType resultSubscriptionType)
        {
            if (_subscriptions.TryGetValue(algorithmId, out ResultSubscriptionType newSubscription))
            {
                // This is an existing subscription. Add requested data
                newSubscription &= resultSubscriptionType;
            }
            else
            {
                // This is a new subscription.
                newSubscription = resultSubscriptionType;

                // When subscribed, we expect the user wants to see data fast.
                // Therefore, we get data from cache, send it, and immediately refresh from the server
                // After subscribing, the polling mechanism will update data further.

                var result = await _cache.GetObject <AlgorithmResult>(algorithmId.DeployId);

                if (result != null)
                {
                    OnAlgorithmResultUpdated(new AlgorithmResultEventArgs(result));
                }
            }

            // Save the subscription
            _subscriptions[algorithmId] = newSubscription;
        }
        public static async Task InsertWithoutOverwriteAsync <T>(this IObjectBlobCache cache, string key, T value,
                                                                 DateTimeOffset expiration) where T : class
        {
            await cache.Flush();

            T fromCache;

            try
            {
                fromCache = await cache.GetObject <T>(key);
            }
            catch (KeyNotFoundException)
            {
                fromCache = null;
            }
            if (fromCache != null)
            {
                await cache.InsertObject(key, value, expiration);
            }
        }
        public static async Task InsertIfMoreDetailsAsync <T>(this IObjectBlobCache cache, string key, T value,
                                                              DateTimeOffset expiration) where T : class, IDetailLeveled
        {
            await cache.Flush();

            IDetailLeveled fromCache;

            try
            {
                fromCache = await cache.GetObject <T>(key);
            }
            catch (KeyNotFoundException)
            {
                fromCache = null;
            }
            var newValue = (IDetailLeveled)value;

            if (fromCache == null || newValue.GetDetailLevel() >= fromCache.GetDetailLevel())
            {
                await cache.InsertObject(key, value, expiration);
            }
        }
        public static async Task InsertAllIfMoreDetailsAsync <T>(this IObjectBlobCache cache,
                                                                 IDictionary <string, T> keyValuePairs, DateTimeOffset expiration) where T : class, IDetailLeveled
        {
            await cache.Flush();

            var toInsert = new Dictionary <string, T>();

            foreach (var pair in keyValuePairs)
            {
                IDetailLeveled fromCache;
                try
                {
                    fromCache = await cache.GetObject <T>(pair.Key);
                }
                catch (KeyNotFoundException)
                {
                    fromCache = null;
                }
                var newValue = (IDetailLeveled)pair.Value;
                if (fromCache == null || newValue.GetDetailLevel() >= fromCache.GetDetailLevel())
                {
                    toInsert.Add(pair.Key, pair.Value);
                }
            }
            if (toInsert.Any())
            {
                try
                {
                    await cache.InsertObjects(toInsert, expiration);
                }
                catch (Exception e)
                {
                    ServiceLocator.Current.GetInstance <ILoggingService>().Report(e, cache);
                }
            }
        }