Пример #1
0
        public async Task <RelationListenResult> ListenAsync(RelationListenConfig listenConfig, Requester requester, CancellationToken token)
        {
            var result = new RelationListenResult()
            {
                lastId = listenConfig.lastId
            };

            var listenId = new RelationListener()
            {
                userId         = requester.userId,
                listenStatuses = listenConfig.statuses
            };

            var maxId = await provider.GetMaxAsync(await provider.GetQueryableAsync <EntityRelation>(), x => x.id);

            if (result.lastId <= 0)
            {
                result.lastId = maxId + result.lastId; //plus because negative
            }
            //This SERIOUSLY requires INTIMATE knowledge of how each of these systems works, like what entityId1 means etc.
            //That's bad.
            result.Relations = await provider.ListenAsync <EntityRelation>(listenId, (q) =>
                                                                           q.Where(x =>
                                                                                   (x.type == Keys.CommentHack ||
                                                                                    x.type == Keys.ModuleHack ||
                                                                                    x.type == Keys.WatchRelation && x.entityId1 == listenId.userId ||
                                                                                    (x.type == Keys.WatchUpdate ||
                                                                                     x.type == Keys.WatchDelete) && x.value.StartsWith($"{listenId.userId}_") ||
                                                                                    x.type.StartsWith(Keys.ActivityKey) ||
                                                                                    x.type.StartsWith(Keys.ModuleMessageKey) && (x.entityId2 == 0 || x.entityId2 == -listenId.userId) ||
                                                                                    x.type.StartsWith(Keys.CommentDeleteHack) ||
                                                                                    x.type.StartsWith(Keys.CommentHistoryHack)) &&
                                                                                   x.id > result.lastId &&
                                                                                   x.id < result.lastId + config.MaxLookahead),
                                                                           systemConfig.ListenTimeout, token);

            //If the read exited with NOTHING, there's nothing in our range. Need to record that
            //so we don't check that range again. This will ALMOST NEVER EVER happen, but it's good to handle the situation.
            //Yes, the listener will have to wait for the full timeout value to get anything, but... well it should be ok.
            if (result.Relations == null || result.Relations.Count == 0)
            {
                result.lastId += config.MaxLookahead;
            }
            else
            {
                result.lastId = result.Relations.Max(x => x.id);
            }

            return(result);
        }
        public async Task <List <EntityRelation> > ListenAsync(RelationListenConfig listenConfig, Requester requester, CancellationToken token)
        {
            var listenId = new RelationListener()
            {
                userId         = requester.userId,
                listenStatuses = listenConfig.statuses
            };

            var maxId = await provider.GetMaxAsync(provider.GetQueryable <EntityRelation>(), x => x.id);

            if (listenConfig.lastId <= 0)
            {
                listenConfig.lastId = maxId + listenConfig.lastId; //plus because negative
            }
            else if (maxId - listenConfig.lastId > 1000)
            {
                throw new BadRequestException($"LastID too far back! Perhaps restart your listener! System current max: {maxId}");
            }

            //This SERIOUSLY requires INTIMATE knowledge of how each of these systems works, like what entityId1 means etc.
            //That's bad.
            var results = await provider.ListenAsync <EntityRelation>(listenId, (q) =>
                                                                      q.Where(x =>
                                                                              (x.type == Keys.CommentHack ||
                                                                               x.type == Keys.WatchRelation && x.entityId1 == listenId.userId ||
                                                                               (x.type == Keys.WatchUpdate ||
                                                                                x.type == Keys.WatchDelete) && x.value.StartsWith($"{listenId.userId}_") ||
                                                                               x.type.StartsWith(Keys.ActivityKey) ||
                                                                               x.type.StartsWith(Keys.ModuleMessageKey) && (x.entityId2 == 0 || x.entityId2 == -requester.userId) ||
                                                                               x.type.StartsWith(Keys.CommentDeleteHack) ||
                                                                               x.type.StartsWith(Keys.CommentHistoryHack)) &&
                                                                              x.id > listenConfig.lastId),
                                                                      systemConfig.ListenTimeout, token);

            return(results);
        }