コード例 #1
0
        public override async Task <TimeStampFeedEntries> GetTimeStampServers(CancellationToken cancellationToken = default)
        {
            // The following code makes sure that the list of servers is shown in a random order (not to prefer any specific server).
            var originalList = await base.GetTimeStampServers(cancellationToken).ConfigureAwait(false);

            if (originalList?.Servers?.Any() != true)
            {
                return(originalList);
            }

            Logger.Debug("Randomizing the list of timestamp servers...");

            var randomList = new TimeStampFeedEntries
            {
                Servers = new List <TimeStampServerEntry>()
            };

            var rnd = new Random();

            while (originalList.Servers.Any())
            {
                var randomElement = rnd.Next(0, originalList.Servers.Count);
                randomList.Servers.Add(originalList.Servers[randomElement]);
                originalList.Servers.RemoveAt(randomElement);
            }

            return(randomList);
        }
コード例 #2
0
    public override async Task <TimeStampFeedEntries> GetTimeStampServers(CancellationToken cancellationToken = default)
    {
        Logger.Debug("Getting exclusive lock for cached read operation...");
        var gotLock = this.syncObject.WaitOne(TimeSpan.FromSeconds(10));

        try
        {
            if (!gotLock)
            {
                Logger.Debug("Could not get an exclusive lock in 10 seconds, aborting...");
                return(new TimeStampFeedEntries());
            }

            if (this.cache?.Servers != null)
            {
                if (this.lastRead > DateTime.Now.Subtract(this.invalidateAfter))
                {
                    Logger.Debug($"Returning the cached copy of servers (last modification {this.lastRead}) which is not older than {this.invalidateAfter} ago...");
                    return(this.cache);
                }


                Logger.Debug($"Invalidating the cached copy of servers (last modification {this.lastRead}) which was older than {this.invalidateAfter} ago...");
                this.cache    = null;
                this.lastRead = DateTime.MinValue;
            }

            var file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData, Environment.SpecialFolderOption.DoNotVerify), "msix-hero", "timestamps.json");

            bool commit;
            if (File.Exists(file))
            {
                var lastDate = File.GetLastWriteTimeUtc(file);
                if (lastDate > DateTime.UtcNow.Subtract(this.invalidateAfter))
                {
                    Logger.Debug($"Returning the local copy of servers from file {file} (last modification {lastDate}) which is not older than {this.invalidateAfter} ago...");
                    // the file is in accepted date range, so we can deserialize it and return the results
                    await using var fs = await this.OpenStream(cancellationToken).ConfigureAwait(false);

                    this.cache = await this.GetTimeStampServers(fs, cancellationToken).ConfigureAwait(false);

                    commit = false;
                }
                else
                {
                    Logger.Debug($"Invalidating the cached copy of servers from file {file} (last modification {lastDate}) which is older than {this.invalidateAfter} ago...");
                    this.cache = await this.decoratedFeed.GetTimeStampServers(cancellationToken).ConfigureAwait(false);

                    this.lastRead = DateTime.UtcNow;
                    Logger.Info($"New last read date is {this.lastRead}.");
                    commit = true;
                }
            }
            else
            {
                Logger.Debug("There is no cached copy available, getting the list from the actual provider...");
                this.cache = await this.decoratedFeed.GetTimeStampServers(cancellationToken).ConfigureAwait(false);

                this.lastRead = DateTime.UtcNow;
                Logger.Info($"New last read date is {this.lastRead}.");
                commit = true;
            }

            if (commit)
            {
                var fileInfo = new FileInfo(file);
                if (fileInfo.Exists)
                {
                    Logger.Info($"Deleting existing cached copy {fileInfo.FullName}...");
                    fileInfo.Delete();
                }
                else if (fileInfo.Directory?.Exists == false)
                {
                    Logger.Info($"Creating directory {fileInfo.Directory.FullName}...");
                    fileInfo.Directory.Create();
                }

                Logger.Debug($"Serializing cached entries into JSON format...");
                var jsonString = JsonConvert.SerializeObject(this.cache, Formatting.Indented);
                Logger.Debug($"Writing cached entries in JSON format into {fileInfo.FullName}...");
                await File.WriteAllTextAsync(fileInfo.FullName, jsonString, cancellationToken).ConfigureAwait(false);
            }

            return(this.cache);
        }
        finally
        {
            if (gotLock)
            {
                Logger.Debug("Returning from exclusive lock...");
                this.syncObject.Set();
            }
        }
    }