Snažím sa prejsť z memcached do redis pomocouklient ServiceStack.Redis. Chcel by som byť schopný jednoducho skontrolovať, či má vyrovnávacia pamäť Redis položky podľa kľúča a ak ich nepridáte s vypršaním platnosti. Neskôr ich vyhľadajte, ak existujú.
Aby som to otestoval, vytvoril som jednoduchý projekt ASP.NET WebApi a modifikoval som ValuesController týmito dvoma metódami.
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
using (var redisClient = new RedisClient("localhost"))
{
IRedisTypedClient<IEnumerable<SampleEvent>> redis = redisClient.As<IEnumerable<SampleEvent>>();
if (!redis.ContainsKey("urn:medications:25"))
{
var medsWithID25 = new List<SampleEvent>();
medsWithID25.Add(new SampleEvent() { ID = 1, EntityID = "25", Name = "Digoxin" });
medsWithID25.Add(new SampleEvent() { ID = 2, EntityID = "25", Name = "Aspirin" });
redis.SetEntry("urn:medications:25", medsWithID25);
redis.ExpireIn("urn:medications:25", TimeSpan.FromSeconds(30));
}
}
return new string[] { "1", "2" };
}
public SampleEvent Get(int id)
{
using (var redisClient = new RedisClient("localhost"))
{
IRedisTypedClient<IEnumerable<SampleEvent>> redis = redisClient.As<IEnumerable<SampleEvent>>();
IEnumerable<SampleEvent> events = redis.GetById("urn:medications:25");
if (events != null)
{
return events.Where(m => m.ID == id).SingleOrDefault();
}
else
return null;
}
}
}
Zdá sa, že to nefunguje. Redis.GetById sa vždy vracia null. Čo robím zle?
Vďaka.
UPDATE 1:
Ak zmením riadok, do ktorého dostanem údaje:
IEnumerable<SampleEvent> events = redis.GetValue("urn:medications:25");
Potom dostanem svoje objekty späť, ale aj po uplynutí časového limitu sme ich mali odstrániť.
odpovede:
2 pre odpoveď č. 1Ok, myslím, že som na to prišiel. Zdá sa, že ide o chybu s typedRedisClient a / alebo o spôsob, akým sa manipuluje s kľúčmi.
Tu uverejním svoje riešenie pre kohokoľvek inéhoProblémy s týmto jednoduchým scenárom, v ktorom chcem používať Redis ako trvalú vyrovnávaciu pamäť a nezaujíma ma ďalšia funkčnosť pre sady, hass, atď ...
Pridajte nasledujúcu metódu rozšírenia:
using System;
using System.Text;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using ServiceStack.OrmLite;
using ServiceStack.Common;
using ServiceStack.Common.Utils;
using ServiceStack.DesignPatterns.Model;
using ServiceStack.ServiceInterface;
using ServiceStack.CacheAccess;
using ServiceStack.ServiceHost;
using ServiceStack.Redis;
namespace Redis.Extensions
{
public static class RedisExtensions
{
internal static T GetFromCache<T>(this IRedisClient redisClient, string cacheKey,
Func<T> factoryFn,
TimeSpan expiresIn)
{
var res = redisClient.Get<T>(cacheKey);
if (res != null)
{
redisClient.Set<T>(cacheKey, res, expiresIn);
return res;
}
else
{
res = factoryFn();
if (res != null) redisClient.Set<T>(cacheKey, res, expiresIn);
return res;
}
}
}
}
A potom zmením svoj testovací kód na tento. Je zrejmé, že je to nedbalé a je potrebné ho vylepšiť, ale aspoň moje testy fungujú podľa očakávania.
using ServiceStack.Redis;
using ServiceStack.Redis.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Redis.Extensions;
namespace RedisTestsWithBooksleeve.Controllers
{
public class SampleEvent
{
public int ID { get; set; }
public string EntityID { get; set; }
public string Name { get; set; }
}
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
using (var redisClient = new RedisClient("localhost"))
{
if (!redisClient.ContainsKey("Meds25"))
{
redisClient.GetFromCache<IEnumerable<SampleEvent>>("Meds25", () => {
var medsWithID25 = new List<SampleEvent>();
medsWithID25.Add(new SampleEvent() { ID = 1, EntityID = "25", Name = "Digoxin" });
medsWithID25.Add(new SampleEvent() { ID = 2, EntityID = "25", Name = "Aspirin" });
return medsWithID25;
}, TimeSpan.FromSeconds(5));
}
}
return new string[] { "1", "2" };
}
public SampleEvent Get(int id)
{
using (var redisClient = new RedisClient("localhost"))
{
IEnumerable<SampleEvent> events = redisClient.GetFromCache<IEnumerable<SampleEvent>>("Meds25", () =>
{
var medsWithID25 = new List<SampleEvent>();
medsWithID25.Add(new SampleEvent() { ID = 1, EntityID = "25", Name = "Digoxin" });
medsWithID25.Add(new SampleEvent() { ID = 2, EntityID = "25", Name = "Aspirin" });
return medsWithID25;
}, TimeSpan.FromSeconds(5));
if (events != null)
{
return events.Where(m => m.ID == id).SingleOrDefault();
}
else
return null;
}
}
}
}