private async Task <RedisValue> MemoLockWithoutSubscriptionAsync(MemoKey key, Func <CancellationToken, Task <RedisValue> > generator, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { throw new TaskCanceledException(); } var result = await TryGetCachedValue(key).ConfigureAwait(false); if (result != null) { return(result.Value); } if (cancellationToken.IsCancellationRequested) { throw new TaskCanceledException(); } try { return(await _lockService.LockAsync(key.GetLockKey(), async c => { //in case we missed the publication var result = await TryGetCachedValue(key).ConfigureAwait(false); if (result != null) { return result.Value; } return await LockedCallback(key, generator, c).ConfigureAwait(false); }, cancellationToken).ConfigureAwait(false)); } catch (TaskCanceledException) { result = await TryGetCachedValue(key).ConfigureAwait(false); if (result != null) { return(result.Value); } throw; } }
private async Task <RedisValue> LockedCallback(MemoKey key, Func <CancellationToken, Task <RedisValue> > generator, CancellationToken token) { if (token.IsCancellationRequested) { throw new TaskCanceledException(); } try { var result = await generator(token).ConfigureAwait(false); await _scriptLibrary.PublishAsync(new MemoSetValueParameters(key, result)).ConfigureAwait(false); return(result); } catch (Exception e) { await _scriptLibrary.PublishAsync(new MemoSetValueParameters(key, e)).ConfigureAwait(false); throw; } }