mirror of
https://git.teknik.io/Teknikode/Teknik.git
synced 2023-08-02 14:16:22 +02:00
- Added cache control for pastes.
- Made updates not need to re-query for data.
This commit is contained in:
parent
035c927326
commit
c7fc3b8658
@ -276,7 +276,7 @@ namespace Teknik.Areas.Admin.Controllers
|
|||||||
uploadController.ControllerContext = context;
|
uploadController.ControllerContext = context;
|
||||||
return uploadController.Delete(id);
|
return uploadController.Delete(id);
|
||||||
case "paste":
|
case "paste":
|
||||||
var pasteController = new Paste.Controllers.PasteController(_logger, _config, _dbContext);
|
var pasteController = new Paste.Controllers.PasteController(_logger, _config, _dbContext, queue);
|
||||||
pasteController.ControllerContext = context;
|
pasteController.ControllerContext = context;
|
||||||
return pasteController.Delete(id);
|
return pasteController.Delete(id);
|
||||||
case "shortenedUrl":
|
case "shortenedUrl":
|
||||||
|
@ -30,7 +30,12 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
[Area("Paste")]
|
[Area("Paste")]
|
||||||
public class PasteController : DefaultController
|
public class PasteController : DefaultController
|
||||||
{
|
{
|
||||||
public PasteController(ILogger<Logger> logger, Config config, TeknikEntities dbContext) : base(logger, config, dbContext) { }
|
private readonly IBackgroundTaskQueue _queue;
|
||||||
|
|
||||||
|
public PasteController(ILogger<Logger> logger, Config config, TeknikEntities dbContext, IBackgroundTaskQueue queue) : base(logger, config, dbContext)
|
||||||
|
{
|
||||||
|
_queue = queue;
|
||||||
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[TrackPageView]
|
[TrackPageView]
|
||||||
@ -46,23 +51,29 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
[TrackPageView]
|
[TrackPageView]
|
||||||
public async Task<IActionResult> ViewPaste(string type, string url, string password)
|
public async Task<IActionResult> ViewPaste(string type, string url, string password)
|
||||||
{
|
{
|
||||||
Models.Paste paste = _dbContext.Pastes.Where(p => p.Url == url).FirstOrDefault();
|
Models.Paste paste = PasteHelper.GetPaste(_dbContext, url);
|
||||||
if (paste != null)
|
if (paste != null)
|
||||||
{
|
{
|
||||||
ViewBag.Title = (string.IsNullOrEmpty(paste.Title)) ? "Untitled Paste" : paste.Title + " | Pastebin";
|
ViewBag.Title = (string.IsNullOrEmpty(paste.Title)) ? "Untitled Paste" : paste.Title + " | Pastebin";
|
||||||
ViewBag.Description = "Paste your code or text easily and securely. Set an expiration, set a password, or leave it open for the world to see.";
|
ViewBag.Description = "Paste your code or text easily and securely. Set an expiration, set a password, or leave it open for the world to see.";
|
||||||
// Increment Views
|
|
||||||
paste.Views += 1;
|
string fileName = paste.FileName;
|
||||||
_dbContext.Entry(paste).State = EntityState.Modified;
|
string key = paste.Key;
|
||||||
_dbContext.SaveChanges();
|
string iv = paste.IV;
|
||||||
|
int blockSize = paste.BlockSize;
|
||||||
|
int keySize = paste.KeySize;
|
||||||
|
string hashedPass = paste.HashedPassword;
|
||||||
|
|
||||||
// Check Expiration
|
// Check Expiration
|
||||||
if (PasteHelper.CheckExpiration(paste))
|
if (PasteHelper.CheckExpiration(paste))
|
||||||
{
|
{
|
||||||
PasteHelper.DeleteFile(_dbContext, _config, _logger, paste);
|
PasteHelper.DeleteFile(_dbContext, _config, _logger, url);
|
||||||
return new StatusCodeResult(StatusCodes.Status404NotFound);
|
return new StatusCodeResult(StatusCodes.Status404NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increment View Count
|
||||||
|
PasteHelper.IncrementViewCount(_queue, _config, url);
|
||||||
|
|
||||||
PasteViewModel model = new PasteViewModel();
|
PasteViewModel model = new PasteViewModel();
|
||||||
model.Url = url;
|
model.Url = url;
|
||||||
model.Title = paste.Title;
|
model.Title = paste.Title;
|
||||||
@ -79,11 +90,11 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] ivBytes = (string.IsNullOrEmpty(paste.IV)) ? new byte[paste.BlockSize] : Encoding.Unicode.GetBytes(paste.IV);
|
byte[] ivBytes = (string.IsNullOrEmpty(iv)) ? new byte[blockSize] : Encoding.Unicode.GetBytes(iv);
|
||||||
byte[] keyBytes = (string.IsNullOrEmpty(paste.Key)) ? new byte[paste.KeySize] : AesCounterManaged.CreateKey(paste.Key, ivBytes, paste.KeySize);
|
byte[] keyBytes = (string.IsNullOrEmpty(key)) ? new byte[keySize] : AesCounterManaged.CreateKey(key, ivBytes, keySize);
|
||||||
|
|
||||||
// The paste has a password set
|
// The paste has a password set
|
||||||
if (!string.IsNullOrEmpty(paste.HashedPassword))
|
if (!string.IsNullOrEmpty(hashedPass))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(password))
|
if (string.IsNullOrEmpty(password))
|
||||||
{
|
{
|
||||||
@ -93,17 +104,17 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
string hash = string.Empty;
|
string hash = string.Empty;
|
||||||
if (!string.IsNullOrEmpty(password))
|
if (!string.IsNullOrEmpty(password))
|
||||||
{
|
{
|
||||||
hash = Crypto.HashPassword(paste.Key, password);
|
hash = Crypto.HashPassword(key, password);
|
||||||
keyBytes = AesCounterManaged.CreateKey(password, ivBytes, paste.KeySize);
|
keyBytes = AesCounterManaged.CreateKey(password, ivBytes, keySize);
|
||||||
}
|
}
|
||||||
if (string.IsNullOrEmpty(password) || hash != paste.HashedPassword)
|
if (string.IsNullOrEmpty(password) || hash != hashedPass)
|
||||||
{
|
{
|
||||||
PasswordViewModel passModel = new PasswordViewModel();
|
PasswordViewModel passModel = new PasswordViewModel();
|
||||||
passModel.ActionUrl = Url.SubRouteUrl("p", "Paste.View", new { type = type, url = url });
|
passModel.ActionUrl = Url.SubRouteUrl("p", "Paste.View", new { type = type, url = url });
|
||||||
passModel.Url = url;
|
passModel.Url = url;
|
||||||
passModel.Type = type;
|
passModel.Type = type;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(password) && hash != paste.HashedPassword)
|
if (!string.IsNullOrEmpty(password) && hash != hashedPass)
|
||||||
{
|
{
|
||||||
passModel.Error = true;
|
passModel.Error = true;
|
||||||
passModel.ErrorMessage = "Invalid Password";
|
passModel.ErrorMessage = "Invalid Password";
|
||||||
@ -118,10 +129,10 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
CachePassword(url, password);
|
CachePassword(url, password);
|
||||||
|
|
||||||
// Read in the file
|
// Read in the file
|
||||||
if (string.IsNullOrEmpty(paste.FileName))
|
if (string.IsNullOrEmpty(fileName))
|
||||||
return new StatusCodeResult(StatusCodes.Status404NotFound);
|
return new StatusCodeResult(StatusCodes.Status404NotFound);
|
||||||
var storageService = StorageServiceFactory.GetStorageService(_config.PasteConfig.StorageConfig);
|
var storageService = StorageServiceFactory.GetStorageService(_config.PasteConfig.StorageConfig);
|
||||||
var fileStream = storageService.GetFile(paste.FileName);
|
var fileStream = storageService.GetFile(fileName);
|
||||||
if (fileStream == null)
|
if (fileStream == null)
|
||||||
return new StatusCodeResult(StatusCodes.Status404NotFound);
|
return new StatusCodeResult(StatusCodes.Status404NotFound);
|
||||||
|
|
||||||
@ -205,7 +216,7 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
[TrackPageView]
|
[TrackPageView]
|
||||||
public async Task<IActionResult> Edit(string url, string password)
|
public async Task<IActionResult> Edit(string url, string password)
|
||||||
{
|
{
|
||||||
Models.Paste paste = _dbContext.Pastes.Where(p => p.Url == url).FirstOrDefault();
|
Models.Paste paste = PasteHelper.GetPaste(_dbContext, url);
|
||||||
if (paste != null)
|
if (paste != null)
|
||||||
{
|
{
|
||||||
if (paste.User?.Username != User.Identity.Name)
|
if (paste.User?.Username != User.Identity.Name)
|
||||||
@ -217,7 +228,7 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
// Check Expiration
|
// Check Expiration
|
||||||
if (PasteHelper.CheckExpiration(paste))
|
if (PasteHelper.CheckExpiration(paste))
|
||||||
{
|
{
|
||||||
PasteHelper.DeleteFile(_dbContext, _config, _logger, paste);
|
PasteHelper.DeleteFile(_dbContext, _config, _logger, url);
|
||||||
return new StatusCodeResult(StatusCodes.Status404NotFound);
|
return new StatusCodeResult(StatusCodes.Status404NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +303,7 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Models.Paste paste = _dbContext.Pastes.Where(p => p.Url == model.Url).FirstOrDefault();
|
Models.Paste paste = PasteHelper.GetPaste(_dbContext, model.Url);
|
||||||
if (paste != null)
|
if (paste != null)
|
||||||
{
|
{
|
||||||
if (paste.User?.Username != User.Identity.Name)
|
if (paste.User?.Username != User.Identity.Name)
|
||||||
@ -350,8 +361,7 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
paste.Syntax = model.Syntax;
|
paste.Syntax = model.Syntax;
|
||||||
paste.DateEdited = DateTime.Now;
|
paste.DateEdited = DateTime.Now;
|
||||||
|
|
||||||
_dbContext.Entry(paste).State = EntityState.Modified;
|
PasteHelper.ModifyPaste(_dbContext, paste);
|
||||||
_dbContext.SaveChanges();
|
|
||||||
|
|
||||||
// Delete the old file
|
// Delete the old file
|
||||||
storageService.DeleteFile(oldFile);
|
storageService.DeleteFile(oldFile);
|
||||||
@ -371,13 +381,13 @@ namespace Teknik.Areas.Paste.Controllers
|
|||||||
[HttpOptions]
|
[HttpOptions]
|
||||||
public IActionResult Delete(string id)
|
public IActionResult Delete(string id)
|
||||||
{
|
{
|
||||||
Models.Paste foundPaste = _dbContext.Pastes.Where(p => p.Url == id).FirstOrDefault();
|
Models.Paste foundPaste = PasteHelper.GetPaste(_dbContext, id);
|
||||||
if (foundPaste != null)
|
if (foundPaste != null)
|
||||||
{
|
{
|
||||||
if (foundPaste.User?.Username == User.Identity.Name ||
|
if (foundPaste.User?.Username == User.Identity.Name ||
|
||||||
User.IsInRole("Admin"))
|
User.IsInRole("Admin"))
|
||||||
{
|
{
|
||||||
PasteHelper.DeleteFile(_dbContext, _config, _logger, foundPaste);
|
PasteHelper.DeleteFile(_dbContext, _config, _logger, id);
|
||||||
|
|
||||||
return Json(new { result = true, redirect = Url.SubRouteUrl("p", "Paste.Index") });
|
return Json(new { result = true, redirect = Url.SubRouteUrl("p", "Paste.Index") });
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,15 @@ using System.IO;
|
|||||||
using Teknik.StorageService;
|
using Teknik.StorageService;
|
||||||
using Teknik.Logging;
|
using Teknik.Logging;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Teknik.Areas.Paste
|
namespace Teknik.Areas.Paste
|
||||||
{
|
{
|
||||||
public static class PasteHelper
|
public static class PasteHelper
|
||||||
{
|
{
|
||||||
|
private static object _cacheLock = new object();
|
||||||
|
private readonly static ObjectCache _pasteCache = new ObjectCache(300);
|
||||||
|
|
||||||
public static Models.Paste CreatePaste(Config config, TeknikEntities db, string content, string title = "", string syntax = "text", ExpirationUnit expireUnit = ExpirationUnit.Never, int expireLength = 1, string password = "")
|
public static Models.Paste CreatePaste(Config config, TeknikEntities db, string content, string title = "", string syntax = "text", ExpirationUnit expireUnit = ExpirationUnit.Never, int expireLength = 1, string password = "")
|
||||||
{
|
{
|
||||||
Models.Paste paste = new Models.Paste();
|
Models.Paste paste = new Models.Paste();
|
||||||
@ -120,8 +124,42 @@ namespace Teknik.Areas.Paste
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DeleteFile(TeknikEntities db, Config config, ILogger<Logger> logger, Models.Paste paste)
|
public static void IncrementViewCount(IBackgroundTaskQueue queue, Config config, string url)
|
||||||
{
|
{
|
||||||
|
// Fire and forget updating of the download count
|
||||||
|
queue.QueueBackgroundWorkItem(async token =>
|
||||||
|
{
|
||||||
|
var optionsBuilder = new DbContextOptionsBuilder<TeknikEntities>();
|
||||||
|
optionsBuilder.UseSqlServer(config.DbConnection);
|
||||||
|
|
||||||
|
using (TeknikEntities db = new TeknikEntities(optionsBuilder.Options))
|
||||||
|
{
|
||||||
|
var paste = GetPaste(db, url);
|
||||||
|
if (paste != null)
|
||||||
|
{
|
||||||
|
paste.Views++;
|
||||||
|
ModifyPaste(db, paste);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Models.Paste GetPaste(TeknikEntities db, string url)
|
||||||
|
{
|
||||||
|
lock (_cacheLock)
|
||||||
|
{
|
||||||
|
var paste = _pasteCache.GetObject(url, (key) => db.Pastes.FirstOrDefault(up => up.Url == key));
|
||||||
|
|
||||||
|
if (!db.Exists(paste))
|
||||||
|
db.Attach(paste);
|
||||||
|
|
||||||
|
return paste;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteFile(TeknikEntities db, Config config, ILogger<Logger> logger, string url)
|
||||||
|
{
|
||||||
|
var paste = GetPaste(db, url);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var storageService = StorageServiceFactory.GetStorageService(config.PasteConfig.StorageConfig);
|
var storageService = StorageServiceFactory.GetStorageService(config.PasteConfig.StorageConfig);
|
||||||
@ -135,6 +173,28 @@ namespace Teknik.Areas.Paste
|
|||||||
// Delete from the DB
|
// Delete from the DB
|
||||||
db.Pastes.Remove(paste);
|
db.Pastes.Remove(paste);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
|
|
||||||
|
// Remove from the cache
|
||||||
|
lock (_cacheLock)
|
||||||
|
{
|
||||||
|
_pasteCache.DeleteObject(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ModifyPaste(TeknikEntities db, Models.Paste paste)
|
||||||
|
{
|
||||||
|
// Update the cache's copy
|
||||||
|
lock (_cacheLock)
|
||||||
|
{
|
||||||
|
_pasteCache.UpdateObject(paste.Url, paste);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!db.Exists(paste))
|
||||||
|
db.Attach(paste);
|
||||||
|
|
||||||
|
// Update the database
|
||||||
|
db.Entry(paste).State = EntityState.Modified;
|
||||||
|
db.SaveChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,13 +32,10 @@ namespace Teknik.Areas.Upload.Controllers
|
|||||||
[Area("Upload")]
|
[Area("Upload")]
|
||||||
public class UploadController : DefaultController
|
public class UploadController : DefaultController
|
||||||
{
|
{
|
||||||
private const int _cacheLength = 300;
|
|
||||||
private readonly ObjectCache _uploadCache;
|
|
||||||
private readonly IBackgroundTaskQueue _queue;
|
private readonly IBackgroundTaskQueue _queue;
|
||||||
|
|
||||||
public UploadController(ILogger<Logger> logger, Config config, TeknikEntities dbContext, IBackgroundTaskQueue queue) : base(logger, config, dbContext)
|
public UploadController(ILogger<Logger> logger, Config config, TeknikEntities dbContext, IBackgroundTaskQueue queue) : base(logger, config, dbContext)
|
||||||
{
|
{
|
||||||
_uploadCache = new ObjectCache(_cacheLength);
|
|
||||||
_queue = queue;
|
_queue = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ namespace Teknik.Areas.Upload
|
|||||||
|
|
||||||
using (TeknikEntities db = new TeknikEntities(optionsBuilder.Options))
|
using (TeknikEntities db = new TeknikEntities(optionsBuilder.Options))
|
||||||
{
|
{
|
||||||
var upload = db.Uploads.FirstOrDefault(up => up.Url == url);
|
var upload = GetUpload(db, url);
|
||||||
if (upload != null)
|
if (upload != null)
|
||||||
{
|
{
|
||||||
upload.Downloads++;
|
upload.Downloads++;
|
||||||
@ -170,13 +170,18 @@ namespace Teknik.Areas.Upload
|
|||||||
{
|
{
|
||||||
lock (_cacheLock)
|
lock (_cacheLock)
|
||||||
{
|
{
|
||||||
return _uploadCache.GetObject(url, (key) => db.Uploads.FirstOrDefault(up => up.Url == key));
|
var upload = _uploadCache.GetObject(url, (key) => db.Uploads.FirstOrDefault(up => up.Url == key));
|
||||||
|
|
||||||
|
if (!db.Exists(upload))
|
||||||
|
db.Attach(upload);
|
||||||
|
|
||||||
|
return upload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DeleteFile(TeknikEntities db, Config config, ILogger<Logger> logger, string url)
|
public static void DeleteFile(TeknikEntities db, Config config, ILogger<Logger> logger, string url)
|
||||||
{
|
{
|
||||||
var upload = db.Uploads.FirstOrDefault(up => up.Url == url);
|
var upload = GetUpload(db, url);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var storageService = StorageServiceFactory.GetStorageService(config.UploadConfig.StorageConfig);
|
var storageService = StorageServiceFactory.GetStorageService(config.UploadConfig.StorageConfig);
|
||||||
@ -187,15 +192,15 @@ namespace Teknik.Areas.Upload
|
|||||||
logger.LogError(ex, "Unable to delete file: {0}", upload.FileName);
|
logger.LogError(ex, "Unable to delete file: {0}", upload.FileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove from the cache
|
|
||||||
lock (_cacheLock)
|
|
||||||
{
|
|
||||||
_uploadCache.DeleteObject(upload.FileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete from the DB
|
// Delete from the DB
|
||||||
db.Uploads.Remove(upload);
|
db.Uploads.Remove(upload);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
|
|
||||||
|
// Remove from the cache
|
||||||
|
lock (_cacheLock)
|
||||||
|
{
|
||||||
|
_uploadCache.DeleteObject(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ModifyUpload(TeknikEntities db, Models.Upload upload)
|
public static void ModifyUpload(TeknikEntities db, Models.Upload upload)
|
||||||
|
@ -1435,7 +1435,7 @@ namespace Teknik.Areas.Users.Controllers
|
|||||||
uploadController.ControllerContext = context;
|
uploadController.ControllerContext = context;
|
||||||
return uploadController.Delete(id);
|
return uploadController.Delete(id);
|
||||||
case "paste":
|
case "paste":
|
||||||
var pasteController = new Paste.Controllers.PasteController(_logger, _config, _dbContext);
|
var pasteController = new Paste.Controllers.PasteController(_logger, _config, _dbContext, queue);
|
||||||
pasteController.ControllerContext = context;
|
pasteController.ControllerContext = context;
|
||||||
return pasteController.Delete(id);
|
return pasteController.Delete(id);
|
||||||
case "shortenedUrl":
|
case "shortenedUrl":
|
||||||
|
@ -165,5 +165,10 @@ namespace Teknik.Data
|
|||||||
|
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Exists<T>(T entity) where T : class
|
||||||
|
{
|
||||||
|
return this.Set<T>().Local.Any(e => e == entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,35 +23,40 @@ namespace Teknik.Utilities
|
|||||||
if (objectCache.TryGetValue(key, out var result) &&
|
if (objectCache.TryGetValue(key, out var result) &&
|
||||||
result.Item1 > cacheDate.Subtract(new TimeSpan(0, 0, _cacheSeconds)))
|
result.Item1 > cacheDate.Subtract(new TimeSpan(0, 0, _cacheSeconds)))
|
||||||
{
|
{
|
||||||
cacheDate = result.Item1;
|
return (T)result.Item2;
|
||||||
foundObject = (T)result.Item2;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foundObject = getObjectFunc(key);
|
foundObject = getObjectFunc(key);
|
||||||
|
// Update the cache for this key
|
||||||
|
if (foundObject != null)
|
||||||
|
UpdateObject(key, foundObject, cacheDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundObject != null)
|
|
||||||
objectCache[key] = new Tuple<DateTime, object>(cacheDate, foundObject);
|
|
||||||
|
|
||||||
return foundObject;
|
return foundObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateObject<T>(string key, T update)
|
public void UpdateObject<T>(string key, T update)
|
||||||
{
|
{
|
||||||
var cacheDate = DateTime.UtcNow;
|
UpdateObject(key, update, DateTime.UtcNow);
|
||||||
if (objectCache.TryGetValue(key, out var result))
|
}
|
||||||
{
|
|
||||||
if (result.Item1 <= cacheDate.Subtract(new TimeSpan(0, 0, _cacheSeconds)))
|
public void UpdateObject<T>(string key, T update, DateTime cacheTime)
|
||||||
DeleteObject(key);
|
{
|
||||||
else
|
objectCache[key] = new Tuple<DateTime, object>(cacheTime, update);
|
||||||
objectCache[key] = new Tuple<DateTime, object>(result.Item1, update);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteObject(string key)
|
public void DeleteObject(string key)
|
||||||
{
|
{
|
||||||
objectCache.Remove(key);
|
objectCache.Remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CacheValid(string key)
|
||||||
|
{
|
||||||
|
if (objectCache.TryGetValue(key, out var result) &&
|
||||||
|
result.Item1 > DateTime.UtcNow.Subtract(new TimeSpan(0, 0, _cacheSeconds)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user