Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        public static async Task <IComposedObject <T> > LookupOrRetrieveAsync <T>(
            DbRef reference,
            [NotNull] ICacheClient redis,
            [NotNull] Func <DbRef, CancellationToken, Task <T> > retrieveFunction,
            CancellationToken cancellationToken) where T : ObjectBase
        {
            if (reference.Equals(DbRef.Ambiguous) || reference.Equals(DbRef.FailedMatch) ||
                reference.Equals(DbRef.Nothing))
            {
                return(null);
            }

            if (redis == null)
            {
                throw new ArgumentNullException(nameof(redis));
            }

            if (retrieveFunction == null)
            {
                throw new ArgumentNullException(nameof(retrieveFunction));
            }

            if (reference.Equals(DbRef.Nothing))
            {
                return(null);
            }

            if (Cache.Contains(reference))
            {
                return((IComposedObject <T>)Cache.Get(reference));
            }

            var obj = await retrieveFunction.Invoke(reference, cancellationToken);

            if (obj == null)
            {
                return(null);
            }

            var composition = await ComposedObject <T> .CreateAsync(redis, obj, cancellationToken);

            if (composition.Item1)
            {
                // The composition was perfect!  No unresolved references, so cache it as-is.
                Cache.Add(reference, composition.Item2, Policy);
            }

            return(composition.Item2);
        }
Ejemplo n.º 3
0
        public static async Task <IComposedObject <T> > UpdateAsync <T>(
            DbRef reference,
            [NotNull] ICacheClient redis,
            [NotNull] T updatedDataObject,
            CancellationToken cancellationToken)
            where T : ObjectBase
        {
            if (Cache.Contains(reference))
            {
                Cache.Remove(reference);
            }

            var composition = await ComposedObject <T> .CreateAsync(redis, updatedDataObject, cancellationToken);

            if (composition.Item1)
            {
                // The composition was perfect!  No unresolved references, so cache it as-is.
                Cache.Add(reference, composition.Item2, Policy);
            }

            return(composition.Item2);
        }