Update how file changes are handled

Instead of relying on MemoryCache, I am using Rx, per a suggestion from Twitter, which enables me to automatically de-dupe things on the fly instead of using a polling method for a temporary cache.
This commit is contained in:
Den Delimarsky
2021-04-28 18:27:42 -07:00
parent 7d71e8828c
commit c2d54b0733
2 changed files with 13 additions and 29 deletions

View File

@@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20071.2" /> <PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20071.2" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
<PackageReference Include="System.Runtime.Caching" Version="6.0.0-preview.1.21102.12" /> <PackageReference Include="System.Runtime.Caching" Version="6.0.0-preview.1.21102.12" />
</ItemGroup> </ItemGroup>

View File

@@ -6,10 +6,12 @@ using Espresso.Shell.Core;
using Espresso.Shell.Models; using Espresso.Shell.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Specialized;
using System.CommandLine; using System.CommandLine;
using System.CommandLine.Invocation; using System.CommandLine.Invocation;
using System.IO; using System.IO;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Runtime.Caching; using System.Runtime.Caching;
using System.Threading; using System.Threading;
@@ -22,10 +24,6 @@ namespace Espresso.Shell
private static FileSystemWatcher watcher = null; private static FileSystemWatcher watcher = null;
public static Mutex Mutex { get => mutex; set => mutex = value; } public static Mutex Mutex { get => mutex; set => mutex = value; }
private static MemoryCache _memoryCache;
private static CacheItemPolicy _cacheItemPolicy;
private const int CacheExpirationTimeframe = 1000;
static int Main(string[] args) static int Main(string[] args)
{ {
bool instantiated; bool instantiated;
@@ -107,16 +105,8 @@ namespace Espresso.Shell
{ {
// Configuration file is used, therefore we disregard any other command-line parameter // Configuration file is used, therefore we disregard any other command-line parameter
// and instead watch for changes in the file. // and instead watch for changes in the file.
try try
{ {
var cacheConfig = new NameValueCollection()
{
{"CacheMemoryLimitMegabytes", "1"},
{"PollingInterval", TimeSpan.FromMilliseconds(1000).ToString()},
};
_memoryCache = new MemoryCache("EventCache", cacheConfig);
watcher = new FileSystemWatcher watcher = new FileSystemWatcher
{ {
Path = Path.GetDirectoryName(config), Path = Path.GetDirectoryName(config),
@@ -125,12 +115,14 @@ namespace Espresso.Shell
Filter = Path.GetFileName(config) Filter = Path.GetFileName(config)
}; };
_cacheItemPolicy = new CacheItemPolicy() Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
{ h => watcher.Changed += h,
RemovedCallback = HandleCacheRemoval h => watcher.Changed -= h
}; )
.SubscribeOn(TaskPoolScheduler.Default)
watcher.Changed += new FileSystemEventHandler(HandleEspressoConfigChange); .Select(e => e.EventArgs)
.Throttle(TimeSpan.FromMilliseconds(25))
.Subscribe(HandleEspressoConfigChange);
// Initially the file might not be updated, so we need to start processing // Initially the file might not be updated, so we need to start processing
// settings right away. // settings right away.
@@ -166,23 +158,14 @@ namespace Espresso.Shell
new ManualResetEvent(false).WaitOne(); new ManualResetEvent(false).WaitOne();
} }
private static void HandleCacheRemoval(CacheEntryRemovedArguments args) private static void HandleEspressoConfigChange(FileSystemEventArgs fileEvent)
{ {
if (args.RemovedReason != CacheEntryRemovedReason.Expired) return;
var fileEvent = (FileSystemEventArgs)args.CacheItem.Value;
Console.WriteLine("Resetting keep-awake to normal state due to settings change."); Console.WriteLine("Resetting keep-awake to normal state due to settings change.");
ResetNormalPowerState(); ResetNormalPowerState();
Console.WriteLine("Detected a file change. Reacting..."); Console.WriteLine("Detected a file change. Reacting...");
ProcessSettings(fileEvent.FullPath); ProcessSettings(fileEvent.FullPath);
} }
private static void HandleEspressoConfigChange(object sender, FileSystemEventArgs e)
{
_cacheItemPolicy.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds(CacheExpirationTimeframe);
_memoryCache.Set(e.Name, e, _cacheItemPolicy);
}
private static void ProcessSettings(string fullPath) private static void ProcessSettings(string fullPath)
{ {
try try