/// <summary> /// Fix for Lookup1. Uses a cached version of ranges /// </summary> /// <param name="grainIdentity"></param> /// <returns></returns> private Range <int> Lookup2(GrainIdentity grainIdentity) { var shardKey = grainIdentity.ShardKey; return(_shardBatchers.Keys .FirstOrDefault(range => range.Low <= shardKey && (shardKey < range.High || range.HighIsMax))); }
private ShardBatcher LookupShardBatcher(GrainIdentity grainIdentity) { Range<int> range = Lookup2(grainIdentity); ShardBatcher shardBatcher; if (!_shardBatchers.TryGetValue(range, out shardBatcher)) throw new ArgumentOutOfRangeException(string.Format("No batcher found for shard key {0}", grainIdentity.ShardKey)); return shardBatcher; }
async Task IStorageProvider.WriteStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { if (_ignore) { return; } var grainIdentity = GrainIdentity.FromGrainReference(grainType, grainReference); await _dataManager.UpsertStateAsync(grainIdentity, grainState.State); }
private ShardBatcher LookupShardBatcher(GrainIdentity grainIdentity) { Range <int> range = Lookup2(grainIdentity); ShardBatcher shardBatcher; if (!_shardBatchers.TryGetValue(range, out shardBatcher)) { throw new ArgumentOutOfRangeException(string.Format("No batcher found for shard key {0}", grainIdentity.ShardKey)); } return(shardBatcher); }
public async Task<object> ReadStateAsync(GrainIdentity grainIdentity) { Guard.NotNull(grainIdentity, "grainIdentity"); ShardBatcher shardBatcher = LookupShardBatcher(grainIdentity); // We don't want to measure elapsed in case of exception var sw = Stopwatch.StartNew(); var state = await shardBatcher.ReadStateAsync(grainIdentity); Logger.Info("ReadStateAsync for {1} elapsed {0}", sw.Elapsed, grainIdentity.GrainType); return state; }
public async Task UpsertStateAsync(GrainIdentity grainIdentity, object state) { Guard.NotNull(grainIdentity, "grainIdentity"); Guard.NotNull(state, "state"); ShardBatcher shardBatcher = LookupShardBatcher(grainIdentity); // We don't want to measure elapsed in case of exception var sw = Stopwatch.StartNew(); await shardBatcher.UpsertStateAsync(grainIdentity, state); Logger.Info("UpsertStateAsync for {1} elapsed {0}", sw.Elapsed, grainIdentity.GrainType); }
public async Task UpsertStateAsync(GrainIdentity grainIdentity, IDictionary <string, object> state) { Guard.NotNull(grainIdentity, "grainIdentity"); Guard.NotNull(state, "state"); ShardBatcher shardBatcher = LookupShardBatcher(grainIdentity); // We don't want to measure elapsed in case of exception var sw = Stopwatch.StartNew(); await shardBatcher.UpsertStateAsync(grainIdentity, state); Logger.Info("UpsertStateAsync for {1} elapsed {0}", sw.Elapsed, grainIdentity.GrainType); }
public async Task <IDictionary <string, object> > ReadStateAsync(GrainIdentity grainIdentity) { Guard.NotNull(grainIdentity, "grainIdentity"); ShardBatcher shardBatcher = LookupShardBatcher(grainIdentity); // We don't want to measure elapsed in case of exception var sw = Stopwatch.StartNew(); var state = await shardBatcher.ReadStateAsync(grainIdentity); Logger.Info("ReadStateAsync for {1} elapsed {0}", sw.Elapsed, grainIdentity.GrainType); return(state); }
/// <summary> Read state data function for this storage provider. </summary> /// <see cref="IStorageProvider.ReadStateAsync"/> public async Task ReadStateAsync(string grainType, GrainReference grainReference, IGrainState grainState) { var grainIdentity = GrainIdentity.FromGrainReference(grainType, grainReference); if (_ignore) { return; } var state = await _dataManager.ReadStateAsync(grainIdentity); if (state != null) { grainState.State = state; } }
async Task IStorageProvider.ReadStateAsync(string grainType, GrainReference grainReference, GrainState grainState) { var grainIdentity = GrainIdentity.FromGrainReference(grainType, grainReference); if (_ignore) { return; } var state = await _dataManager.ReadStateAsync(grainIdentity); if (null != state) { grainState.SetAll(state); } }
public async Task UpsertStateAsync(GrainIdentity grainIdentity, object state) { // for this specific type of grain choose the batch // Lazy is used to avoid side effects since valueFactory() may be called multiple times on different threads var writeGroup = _writeGroups.GetOrAdd(grainIdentity.GrainType, _ => new Lazy <BatchGroup <WriteEntry> >(() => { var group = new BatchGroup <WriteEntry>(); group.BatchBlock = new BatchBlock <WriteEntry>(BatchSize, new GroupingDataflowBlockOptions() { Greedy = true, BoundedCapacity = BatchSize * 2 }); group.FlushTimer = new Timer(group.FlushBatch, null, TimeSpan.FromSeconds(BatchTimeoutSeconds), TimeSpan.FromSeconds(BatchTimeoutSeconds)); group.Link = group.BatchBlock.LinkTo(_writeActionBlock); Logger.Info("Created WriteGroup for {0} on {1}", grainIdentity.GrainType, _shard.Location.Database); return(group); })).Value; TaskCompletionSource <int> tcs = new TaskCompletionSource <int>(); // use SendAsync instead of Post to allow for buffering posted messages // Post would retrun false when the Block cannot accept a message if (await writeGroup.BatchBlock.SendAsync(new WriteEntry(grainIdentity, state, tcs))) { InstrumentationContext.WritePosted(); } else { tcs.SetException(new ApplicationException("SendAsync did not accept the message")); Logger.Error("UpsertStateAsync batchBlock.SendAsync did not acccept the message"); InstrumentationContext.WritePostFailed(); } await tcs.Task; }
internal WriteEntry(GrainIdentity grainIdentity, object state, TaskCompletionSource <int> tcs) { GrainIdentity = grainIdentity; State = state; CompletionSource = tcs; }
/// <summary> /// Old version of Lookup which leads to hitting sql map db per every request /// which slows down the whole performance /// </summary> /// <param name="grainIdentity"></param> /// <returns></returns> private Range <int> Lookup1(GrainIdentity grainIdentity) { RangeMapping <int> rangeMapping = _shardMap.GetMappingForKey(grainIdentity.ShardKey); return(rangeMapping.Value); }
internal ReadEntry(GrainIdentity grainIdentity, TaskCompletionSource<object> tcs) { GrainIdentity = grainIdentity; CompletionSource = tcs; }
/// <summary> /// Fix for Lookup1. Uses a cached version of ranges /// </summary> /// <param name="grainIdentity"></param> /// <returns></returns> private Range<int> Lookup2(GrainIdentity grainIdentity) { var shardKey = grainIdentity.ShardKey; return _shardBatchers.Keys .FirstOrDefault(range => range.Low <= shardKey && (shardKey < range.High || range.HighIsMax)); }
internal ReadEntry(GrainIdentity grainIdentity, TaskCompletionSource <IDictionary <string, object> > tcs) { GrainIdentity = grainIdentity; CompletionSource = tcs; }
internal ReadEntry(GrainIdentity grainIdentity, TaskCompletionSource <object> tcs) { GrainIdentity = grainIdentity; CompletionSource = tcs; }
/// <summary> /// Old version of Lookup which leads to hitting sql map db per every request /// which slows down the whole performance /// </summary> /// <param name="grainIdentity"></param> /// <returns></returns> private Range<int> Lookup1(GrainIdentity grainIdentity) { RangeMapping<int> rangeMapping = _shardMap.GetMappingForKey(grainIdentity.ShardKey); return rangeMapping.Value; }
internal WriteEntry(GrainIdentity grainIdentity, IDictionary<string, object> state, TaskCompletionSource<int> tcs) { GrainIdentity = grainIdentity; State = state; CompletionSource = tcs; }
internal WriteEntry(GrainIdentity grainIdentity, IDictionary <string, object> state, TaskCompletionSource <int> tcs) { GrainIdentity = grainIdentity; State = state; CompletionSource = tcs; }
internal WriteEntry(GrainIdentity grainIdentity, object state, TaskCompletionSource<int> tcs) { GrainIdentity = grainIdentity; State = state; CompletionSource = tcs; }
internal ReadEntry(GrainIdentity grainIdentity, TaskCompletionSource<IDictionary<string, object>> tcs) { GrainIdentity = grainIdentity; CompletionSource = tcs; }