/// <summary>
        /// Link a queryable entity list with values/relations to produce a list of packaged entities
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="queryable"></param>
        /// <returns></returns>
        public static async Task <List <EntityPackage> > LinkAsync(this IEntityProvider provider, IQueryable <Entity> queryable)
        {
            //Performance test this sometime
            var entities = await provider.GetListAsync(queryable);

            //Oops, there's nothing. Don't bother (we don't need to query the WHOLE database for no entities)
            if (entities.Count == 0)
            {
                return(new List <EntityPackage>());
            }

            var ids    = entities.Select(x => x.id).ToList();
            var values = await provider.GetEntityValuesAsync(new EntityValueSearch()
            {
                EntityIds = ids
            });                                                                                            //Will this stuff be safe?

            var relations = await provider.GetEntityRelationsAsync(new EntityRelationSearch()
            {
                EntityIds2 = ids
            });                                                                                                      //Will this stuff be safe?

            return(entities.Select(x => new EntityPackage()
            {
                Entity = x,
                Values = values.Where(y => y.entityId == x.id).ToList(),
                Relations = relations.Where(y => y.entityId2 == x.id).ToList()
            }).ToList());
        }
        public async Task <Dictionary <long, Dictionary <long, string> > > GetListenersAsync(
            Dictionary <long, Dictionary <long, string> > lastListeners, Requester requester, CancellationToken token)
        {
            DateTime start = DateTime.Now;

            while (DateTime.Now - start < systemConfig.ListenTimeout)
            {
                //logger.LogInformation($"Listen loop for {requester.userId}");

                //It seems strange to update the decayer with the WHOLE LIST but remember: this whole list is the EXACT SNAPSHOT of who's listening
                //RIGHT NOW! because it's "instant", it's ok to continuously update the decayer, when someone leaves, they will appear gone in
                //EVERYONE'S listener list connection
                listenDecayer.UpdateList(GetInstantListeners());

                //Decay the list only once, get the new list of listeners
                var listenersNow = listenDecayer.DecayList(systemConfig.ListenGracePeriod);

                //Creates a dictionary with pre-initialized keys. The keys won't change, we can keep redoing them.
                //This should be OK, considering we'll be creating new dictionaries every time anyway. As always, watch the CPU
                var result = GetListenersAsDictionary(listenersNow, lastListeners.Keys);

                var users = result.Values.SelectMany(x => x.Keys).ToList();

                //A VERY RAW thing (for speed)
                foreach (var hideval in await provider.GetEntityValuesAsync(new EntityValueSearch()
                {
                    EntityIds = users, KeyLike = Keys.UserHideKey
                }))
                {
                    //Parse the actual hide values for this user.
                    var hides = hideval.value.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(x => long.Parse(x));

                    //Now loop through the rooms and completely remove users from lists if they're hiding there
                    foreach (var room in result)
                    {
                        if (hides.Contains(0) || hides.Contains(room.Key))
                        {
                            room.Value.Remove(hideval.entityId);
                        }
                    }
                }

                if (result.Any(x => !x.Value.RealEqual(lastListeners[x.Key])))
                {
                    return(result);
                }

                await Task.Delay(config.ListenerPollingInterval, token);

                token.ThrowIfCancellationRequested();
            }

            throw new TimeoutException("Ran out of time waiting for listeners");
        }
Esempio n. 3
0
        public async Task <ActionResult <TestData> > TestGet()
        {
            var entities = await provider.GetEntitiesAsync(new EntitySearch());                 //This should get all?

            var values = await provider.GetEntityValuesAsync(new EntityValueSearch());          //This should get all?

            var relations = await provider.GetEntityRelationsAsync(new EntityRelationSearch()); //This should get all?

            return(new TestData()
            {
                EntityCount = entities.Count,
                ValueCount = values.Count,
                RelationCount = relations.Count
            });
        }
        public async Task <Dictionary <long, List <EntityValue> > > GetSortedValues <T>(IEnumerable <T> items) where T : BaseSystemObject
        {
            var values = await provider.GetEntityValuesAsync(new EntityValueSearch()
            {
                EntityIds = items.Select(x => x.id).ToList()
            });

            var result = items.Where(x => x.id != 0).ToDictionary(x => x.id, y => new List <EntityValue>());

            result.Add(0, new List <EntityValue>());

            foreach (var value in values)
            {
                result[value.entityId].Add(value);
            }

            return(result);
        }