Exemple #1
0
        public void Add(TKey key, TValue value)
        {
            AdjustSize();
            var result = new TimestampedValue(this, value);

            cache.AddOrUpdate(key, result, (k, o) => result);
        }
Exemple #2
0
        public void Add(TKey key, TValue value)
        {
            AdjustSize();
            var result = new TimestampedValue(this, value);

            cache[key] = result;
        }
Exemple #3
0
        protected async Task <TGrainState> ProcessEvent(TEvent grainEvent)
        {
            var timestampedGrainEvent = new TimestampedValue <TEvent>(grainEvent, DateTime.UtcNow);

            State.Events.Add(timestampedGrainEvent);
            State.CurrentState = State.CurrentState.ApplyEvent(timestampedGrainEvent, State.CurrentState);
            await WriteStateAsync();

            return(State.CurrentState);
        }
Exemple #4
0
        /// <summary>
        /// Get a grain reference for the specified cache-key.
        /// The grain reference will either be taken from cahce, or a new one will be created by calling the <c>FetchValueDelegate</c>
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public TValue Get(TKey key)
        {
            TimestampedValue result;
            bool             readerLockUpgraded = false;

            try
            {
                rwLock.EnterReadLock();

                if (cache.TryGetValue(key, out result))
                {
                    result.Generation = Interlocked.Increment(ref nextGeneration);
                    TimeSpan age = result.WhenLoaded.Subtract(DateTime.UtcNow);
                    if (age > requiredFreshness)
                    {
                        try
                        {
                            rwLock.ExitReadLock();
                            readerLockUpgraded = true;
                            rwLock.EnterWriteLock();
                            cache.Remove(key);
                        }
                        finally
                        {
                            rwLock.ExitWriteLock();
                        }
                        result = null;
                    }
                }

                if (result != null)
                {
                    return(result.Value);
                }
            }
            finally
            {
                if (!readerLockUpgraded)
                {
                    rwLock.ExitReadLock();
                }
            }

            try
            {
                rwLock.EnterWriteLock();

                if (cache.TryGetValue(key, out result))
                {
                    result.Generation = Interlocked.Increment(ref nextGeneration);
                    return(result.Value);
                }

                while (cache.Count >= maximumCount)
                {
                    long generationToDelete = Interlocked.Increment(ref generationToFree);
                    KeyValuePair <TKey, TimestampedValue> entryToFree =
                        cache.FirstOrDefault(kvp => kvp.Value.Generation == generationToDelete);

                    if (entryToFree.Key != null)
                    {
                        cache.Remove(entryToFree.Key);
                    }
                }

                result = new TimestampedValue {
                    Generation = Interlocked.Increment(ref nextGeneration)
                };
                try
                {
                    var r = fetcher(key);
                    result.Value      = r;
                    result.WhenLoaded = DateTime.UtcNow;
                    cache.Add(key, result);
                }
                catch (Exception)
                {
                    if (cache.ContainsKey(key))
                    {
                        cache.Remove(key);
                    }
                    throw;
                }
            }
            finally
            {
                rwLock.ExitWriteLock();
            }
            return(result.Value);
        }
Exemple #5
0
 public BankAccountState ApplyEvent(TimestampedValue <BankAccountOperation> value, BankAccountState currentState)
 {
     return(value.Value.Match(Credit(currentState), Debit(currentState)));
 }
 private static void UpdateTimestamp(TimestampedValue tsValue)
 {
     tsValue.Timestamp = DateTime.UtcNow;                 // no need to lock because at worse another thread will update with only a small difference in time stamp.
 }