fix bugs around retrieving cache items, note that sliding expiration doesn't work properly as of now
This commit is contained in:
@@ -3,6 +3,8 @@ Use azure table storage for AspNet core 1.0 Distributed Cache.
|
||||
|
||||
Azure Table Storage is a very cheap, [super fast](https://www.troyhunt.com/working-with-154-million-records-on/) key value store, and its much cheaper than the redis cluster in azure. This is not a true replacement for redis, and redis should be used if people have money, but this is designed to get people a very cheap cache in azure. Currently this doesn't actually support the dotnet core runtime, and won't until the Azure Storage client is updated to support core.
|
||||
|
||||
**warning** As of right now sliding expiration doesn't work. This is at the top of the list to get working
|
||||
|
||||
## How to use
|
||||
|
||||
`install-package AzureTableStorageCache`
|
||||
@@ -22,7 +24,9 @@ In your startup.cs
|
||||
|
||||
```
|
||||
|
||||
Then in a controller just ask for an IDistributedCache in the constructor. Since this implements Microsoft's IDistributed cache, it could be easily swapped out for redis or another Distributed cache
|
||||
Then in a controller just ask for an IDistributedCache in the constructor. Since this implements Microsoft's IDistributed cache, it could be easily swapped out for redis or another Distributed cache.
|
||||
|
||||
|
||||
|
||||
```csharp
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ namespace AzureTableStorageCache
|
||||
}
|
||||
this.tableName = tableName;
|
||||
this.partitionKey = partitionKey;
|
||||
Connect();
|
||||
}
|
||||
|
||||
public AzureTableStorageCacheHandler(string accountName, string accountKey, string tableName, string partitionKey)
|
||||
@@ -51,6 +50,7 @@ namespace AzureTableStorageCache
|
||||
|
||||
this.accountName = accountName;
|
||||
this.accountKey = accountKey;
|
||||
Connect();
|
||||
}
|
||||
|
||||
private readonly string tableName;
|
||||
@@ -64,6 +64,7 @@ namespace AzureTableStorageCache
|
||||
}
|
||||
|
||||
this.connectionString = connectionString;
|
||||
Connect();
|
||||
}
|
||||
|
||||
public void Connect()
|
||||
@@ -99,10 +100,13 @@ namespace AzureTableStorageCache
|
||||
|
||||
public async Task<byte[]> GetAsync(string key)
|
||||
{
|
||||
await RefreshAsync(key);
|
||||
var op = TableOperation.Retrieve(partitionKey, key);
|
||||
var result = await azuretable.ExecuteAsync(op);
|
||||
return (result?.Result as CachedItem)?.Data;
|
||||
var cachedItem = await RetrieveAsync(key);
|
||||
if (cachedItem != null && cachedItem.Data != null && ShouldDelete(cachedItem))
|
||||
{
|
||||
await RemoveAsync(key);
|
||||
return null;
|
||||
}
|
||||
return cachedItem?.Data;
|
||||
}
|
||||
|
||||
public void Refresh(string key)
|
||||
@@ -112,9 +116,7 @@ namespace AzureTableStorageCache
|
||||
|
||||
public async Task RefreshAsync(string key)
|
||||
{
|
||||
var op = TableOperation.Retrieve(partitionKey, key);
|
||||
var result = await azuretable.ExecuteAsync(op);
|
||||
var data = result?.Result as CachedItem;
|
||||
var data = await RetrieveAsync(key);
|
||||
if (data != null)
|
||||
{
|
||||
if (ShouldDelete(data))
|
||||
@@ -125,6 +127,14 @@ namespace AzureTableStorageCache
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<CachedItem> RetrieveAsync(string key)
|
||||
{
|
||||
var op = TableOperation.Retrieve<CachedItem>(partitionKey, key);
|
||||
var result = await azuretable.ExecuteAsync(op);
|
||||
var data = result?.Result as CachedItem;
|
||||
return data;
|
||||
}
|
||||
|
||||
private bool ShouldDelete(CachedItem data)
|
||||
{
|
||||
var currentTime = DateTimeOffset.UtcNow;
|
||||
@@ -176,6 +186,14 @@ namespace AzureTableStorageCache
|
||||
absoluteExpiration = options.AbsoluteExpiration;
|
||||
}
|
||||
var item = new CachedItem(partitionKey, key, value) { LastAccessTime = currentTime };
|
||||
if (absoluteExpiration.HasValue)
|
||||
{
|
||||
item.AbsolutExperiation = absoluteExpiration;
|
||||
}
|
||||
if (options.SlidingExpiration.HasValue)
|
||||
{
|
||||
item.SlidingExperiation = options.SlidingExpiration;
|
||||
}
|
||||
var op = TableOperation.InsertOrReplace(item);
|
||||
return this.azuretable.ExecuteAsync(op);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "1.1.0-*",
|
||||
"version": "1.2.0-*",
|
||||
|
||||
"dependencies": {
|
||||
"NETStandard.Library": "1.5.0-rc2-24027",
|
||||
|
||||
@@ -19,12 +19,16 @@ namespace AzureTableStorageCacheSample.Controllers
|
||||
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
var data = await cacheMechanism.GetAsync("awesomeRecord");
|
||||
await cacheMechanism.SetAsync("awesomeRecord2", Encoding.UTF32.GetBytes("records are awesome"), new DistributedCacheEntryOptions() { SlidingExpiration = new TimeSpan(0, 5, 0) });
|
||||
var data = await cacheMechanism.GetAsync("awesomeRecord2");
|
||||
var result = string.Empty;
|
||||
if (data != null)
|
||||
{
|
||||
result = Encoding.UTF32.GetString(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
return View(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace AzureTableStorageCacheSample
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddAzureTableStorageCache("!!!CONNECTIONSTRINGHERE!!!", "tablename", "partitionKey");
|
||||
services.AddAzureTableStorageCache("DefaultEndpointsProtocol=https;AccountName=tparnell;AccountKey=cEHdbvM6bljcIYOaODs16vRokLDvxujEn+JR/8MWgYE/9g4mw95n/jusTAdvhc/JrySfZGwaq/WIg9Bi/TeoOw==", "yodawg", "cachingforlyfe");
|
||||
// Add framework services.
|
||||
services.AddMvc();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user