Example #1
0
        public async Task <AnfComicEntityTruck> FetchEntityAsync(IResourceFetchContext context)
        {
            var coll   = mongoClient.GetComicEntityCollection();
            var filter = Builders <AnfComicEntity> .Filter.Eq(x => x.ComicUrl, context.Url);

            var entity = await coll.Find(filter)
                         .FirstOrDefaultAsync();

            var now                   = DateTime.Now.Ticks;
            var isUpdate              = entity != null;
            var needUpdate            = entity != null && (now - entity.UpdateTime) >= fetchOptions.Value.DataTimeout.Ticks;
            AnfComicEntityTruck truck = null;

            if (entity is null || needUpdate)
            {
                using (var locker = await context.CreateEntityLockerAsync())
                {
                    if (!locker.IsAcquired)
                    {
                        if (context.RequireReloopFetcher != this)
                        {
                            context.SetRequireReloop();
                        }
                        return(null);
                    }
                    truck = await remoteFetcher.FetchEntityAsync(context);

                    if (truck != null)
                    {
                        if (needUpdate)
                        {
                            var updater = MakeUpdater(entity);
                            var chps    = truck.Chapters.Select(x => new WithPageChapter
                            {
                                TargetUrl  = x.TargetUrl,
                                CreateTime = now,
                                Title      = x.Title
                            }).ToArray();
                            var originMap = entity.WithPageChapters.GroupBy(x => x.TargetUrl)
                                            .ToDictionary(x => x.Key, x => x.First());
                            foreach (var item in chps)
                            {
                                if (originMap.TryGetValue(item.TargetUrl, out var origin))
                                {
                                    item.Pages      = origin.Pages;
                                    item.UpdateTime = origin.UpdateTime;
                                    item.RefCount   = origin.RefCount;
                                    item.CreateTime = origin.CreateTime;
                                }
                            }
                            updater = updater.Set(x => x.WithPageChapters, chps);
                            var r = await coll.UpdateOneAsync(filter, updater);
                        }
                        else
                        {
                            var val = new AnfComicEntity
                            {
                                ComicUrl         = truck.ComicUrl,
                                CreateTime       = truck.CreateTime,
                                Descript         = truck.Descript,
                                ImageUrl         = truck.ImageUrl,
                                Name             = truck.Name,
                                RefCount         = truck.RefCount,
                                UpdateTime       = truck.UpdateTime,
                                WithPageChapters = truck.Chapters.Select(x => new WithPageChapter
                                {
                                    CreateTime = now,
                                    Title      = x.Title,
                                    TargetUrl  = x.TargetUrl
                                }).ToArray()
                            };
                            await coll.InsertOneAsync(val);
                        }
                    }
                }
            }
            if (truck is null && entity != null)
            {
                truck = new AnfComicEntityTruck
                {
                    CreateTime = entity.CreateTime,
                    ComicUrl   = entity.ComicUrl,
                    Descript   = entity.Descript,
                    ImageUrl   = entity.ImageUrl,
                    Name       = entity.Name,
                    RefCount   = entity.RefCount,
                    UpdateTime = entity.UpdateTime,
                    Chapters   = entity.WithPageChapters.Select(x => new ComicChapter
                    {
                        TargetUrl = x.TargetUrl,
                        Title     = x.Title
                    }).ToArray()
                };
            }
            return(truck);
        }
Example #2
0
        private async Task CoreDoneFetchEntityAsync(IResourceFetchContext ctx, AnfComicEntityTruck val)
        {
            var set   = dbContextTransfer.GetComicEntitySet();
            var now   = DateTime.Now.Ticks;
            var upRes = await set.AsNoTracking()
                        .Where(x => x.ComicUrl == ctx.Url)
                        .Take(1)
                        .UpdateFromQueryAsync(x => new KvComicEntity
            {
                ComicUrl   = val.ComicUrl,
                Name       = val.Name,
                Descript   = val.Descript,
                ImageUrl   = val.ImageUrl,
                UpdateTime = now
            });

            if (upRes != 0)
            {
                var chpSet      = dbContextTransfer.GetComicChapterSet();
                var includeUrls = val.Chapters.Select(x => x.TargetUrl).Distinct().ToArray();
                var query       = chpSet.AsNoTracking();
                if (includeUrls.Length > 50)
                {
                    var urlEntity = includeUrls.Select(x => new { TargetUrl = x }).ToArray();
                    query = query.WhereBulkContains(urlEntity, nameof(KvComicChapter.TargetUrl));
                }
                else
                {
                    query = query.Where(x => includeUrls.Contains(x.TargetUrl));
                }
                var exists = await query.Select(x => x.TargetUrl).ToArrayAsync();

                var  existsHash = new HashSet <string>(exists);
                var  notExists  = new List <KvComicChapter>();
                long id         = -1;
                for (int i = 0; i < val.Chapters.Length; i++)
                {
                    var chp = val.Chapters[i];
                    if (!existsHash.Contains(chp.TargetUrl))
                    {
                        if (id == -1)
                        {
                            id = await set.AsNoTracking()
                                 .Where(x => x.ComicUrl == ctx.Url)
                                 .Select(x => x.Id)
                                 .FirstAsync();
                        }
                        var kvChp = new KvComicChapter
                        {
                            TargetUrl  = chp.TargetUrl,
                            Title      = chp.Title,
                            CreateTime = now,
                            EnitityId  = id,
                            Order      = existsHash.Count + notExists.Count + 1
                        };
                        notExists.Add(kvChp);
                    }
                }
                if (notExists.Count != 0)
                {
                    await chpSet.BulkInsertAsync(notExists);
                }
            }
            else
            {
                var index  = 1;
                var entity = new KvComicEntity
                {
                    ComicUrl   = val.ComicUrl,
                    Descript   = val.Descript,
                    ImageUrl   = val.ImageUrl,
                    Name       = val.Name,
                    UpdateTime = now,
                    CreateTime = now,
                    Chapters   = val.Chapters.Select(x => new KvComicChapter
                    {
                        Order      = index++,
                        CreateTime = now,
                        Title      = x.Title,
                    }).ToArray(),
                };
                await set.SingleInsertAsync(entity);

                var chpSet = dbContextTransfer.GetComicChapterSet();
                await chpSet.BulkInsertAsync(entity.Chapters);
            }
        }