public void Add(TKey key, TValue value) { AdjustSize(); var result = new TimestampedValue(this, value); cache.AddOrUpdate(key, result, (k, o) => result); }
public void Add(TKey key, TValue value) { AdjustSize(); var result = new TimestampedValue(this, value); cache[key] = result; }
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); }
/// <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); }
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. }