public static async Task <Tuple <bool, IComposedObject <T> > > CreateAsync([NotNull] ICacheClient redis, [NotNull] T dataObject, CancellationToken cancellationToken) { if (redis == null) { throw new ArgumentNullException(nameof(redis)); } if (dataObject == null) { throw new ArgumentNullException(nameof(dataObject)); } var ret = new ComposedObject <T>(dataObject); var perfect = true; var taskLocation = Task.Run( async() => { var composedLocation = await CacheManager.LookupOrRetrieveAsync <ObjectBase>(dataObject.Location, redis, async(d, token) => await Room.GetAsync(redis, dataObject.Location, token), cancellationToken); ret.Location = composedLocation; perfect = perfect && (dataObject.Location <= 0 || composedLocation != null); }, cancellationToken); if (dataObject.Contents != null) { var contents = new List <IComposedObject <ObjectBase> >(); Parallel.ForEach( dataObject.Contents, async dbref => { var composedContent = await CacheManager.LookupOrRetrieveAsync(dbref, redis, async(d, token) => await ObjectBase.GetAsync(redis, d, token), cancellationToken); if (composedContent != null) { contents.Add(composedContent); } perfect = perfect && (dbref <= 0 || composedContent != null); }); ret.Contents = contents.AsReadOnly(); } var taskParent = Task.Run( async() => { var composedParent = await CacheManager.LookupOrRetrieveAsync(dataObject.Parent, redis, async(d, token) => await ObjectBase.GetAsync(redis, dataObject.Parent, token), cancellationToken); ret.Parent = composedParent; perfect = perfect && (dataObject.Parent <= 0 || composedParent != null); }, cancellationToken); // ReSharper disable once PossibleNullReferenceException await Task.WhenAll(taskLocation, taskParent); return(new Tuple <bool, IComposedObject <T> >(perfect, ret)); }
/// <inheritdoc /> public async Task MoveAsync(DbRef newLocation, ICacheClient redis, CancellationToken cancellationToken) { if (redis == null) { throw new ArgumentNullException(nameof(redis)); } Debug.Assert(!newLocation.Equals(DbRef.Nothing), "!newLocation.Equals(DbRef.NOTHING)"); Debug.Assert(!newLocation.Equals(DbRef.Ambiguous), "!newLocation.Equals(DbRef.AMBIGUOUS)"); Debug.Assert(!newLocation.Equals(DbRef.FailedMatch), "!newLocation.Equals(DbRef.FAILED_MATCH)"); if (redis == null) { throw new ArgumentNullException(nameof(redis)); } if (this.Location.Equals(newLocation)) { return; } var oldLocationObject = this.Location.Equals(DbRef.Nothing) ? null : await CacheManager.LookupOrRetrieveAsync(this.Location, redis, async (d, token) => await GetAsync(redis, d, token), cancellationToken); var newLocationObject = await CacheManager.LookupOrRetrieveAsync(newLocation, redis, async (d, token) => await GetAsync(redis, d, token), cancellationToken); if (newLocationObject != null) { if (oldLocationObject != null) { oldLocationObject.DataObject.RemoveContents(this.DbRef); await oldLocationObject.DataObject.SaveAsync(redis, cancellationToken); } newLocationObject.DataObject.AddContents(this.DbRef); await newLocationObject.DataObject.SaveAsync(redis, cancellationToken); this.Location = newLocation; await this.SaveAsync(redis, cancellationToken); var genericUpdateAsync = typeof(CacheManager).GetMethod(nameof(CacheManager.UpdateAsync)).MakeGenericMethod(newLocationObject.DataObject.GetType()); var task = (Task)genericUpdateAsync.Invoke(null, new object[] { newLocation, redis, newLocationObject.DataObject, cancellationToken }); Debug.Assert(task != null, "task != null"); await task; } }
/// <inheritdoc /> public async Task ReparentAsync(DbRef newParent, ICacheClient redis, CancellationToken cancellationToken) { Debug.Assert(!newParent.Equals(DbRef.Nothing), "!newParent.Equals(DbRef.NOTHING)"); Debug.Assert(!newParent.Equals(DbRef.Ambiguous), "!newParent.Equals(DbRef.AMBIGUOUS)"); Debug.Assert(!newParent.Equals(DbRef.FailedMatch), "!newParent.Equals(DbRef.FAILED_MATCH)"); if (redis == null) { throw new ArgumentNullException(nameof(redis)); } var newParentObject = await CacheManager.LookupOrRetrieveAsync(newParent, redis, async (d, token) => await GetAsync(redis, d, token), cancellationToken); if (newParentObject != null) { this.Parent = newParent; await this.SaveAsync(redis, cancellationToken); } }
public static new async Task <Player> GetAsync([NotNull] ICacheClient redis, DbRef playerRef, CancellationToken cancellationToken) => (await CacheManager.LookupOrRetrieveAsync(playerRef, redis, async(d, token) => await redis.GetAsync <Player>($"mudpie::player:{d}"), cancellationToken))?.DataObject;