ServiceStack REST服务的缓存策略

时间:2013-01-29 02:44:15

标签: caching servicestack

我有一个简单的Orders服务,并希望实现缓存。这是我的请求/回复和服务:

[Route("/order", "GET")]
[Route("/order/{Id}", "GET")]
public class OrderRequest : IReturn<OrderResponse>
{
    public int Id { get; set; }

    public string Reference1 { get; set; }

    public string Reference2 { get; set; }

    public DateRange CreatedOn { get; set; }

    public DateRange ProcessedOn { get; set; }

    public DateRange ShippedOn { get; set; }

    public DateRange ModifiedOn { get; set; }
}

public class OrderResponse : IHasResponseStatus 
{
    public ResponseStatus ResponseStatus { get; set; }

    public List<Order> Orders { get; set; }
}

public class OrdersService : Service
{
    public object Get(OrderRequest request)
    {
        var cacheKey = UrnId.Create<OrderResponse>(request.Id.ToString());
        return base.RequestContext.ToOptimizedResultUsingCache(base.Cache, cacheKey, new TimeSpan(0,5,0), () =>
        {
            return GetOrders(request);
        });
    }

    public OrderResponse GetOrders(OrderRequest request)
    {
        ..
    }
}

查看文档,为每个缓存项生成唯一键。在示例中,这通常是响应对象+项ID。但是我想缓存不同类型的请求。例如,在我的请求中,我可以指定日期范围。如果我使用相同的日期范围发出相同的请求,那么我希望收到缓存的副本。所以我的问题是,基于部分或全部请求参数生成唯一ID的最佳方法是什么?也许在请求DTO上使用或覆盖GetHashCode?其次,如果我的缓存包含许多相同类型的对象,即OrderResponse,我可以删除给定类型的所有项吗?否则,如果我修改了一个订单,我将不知道要删除哪个缓存对象。

1 个答案:

答案 0 :(得分:1)

cacheKey没有什么特别或重要的,它只需要对要缓存的每个不同项或结果集都是唯一的。

如果您希望它支持指定日期范围的不同缓存,则需要将变量信息添加到密钥。您可以在Request DTO上使用唯一属性的组合,也可以使用base.Request.PathInfo和/或QueryString来创建用作缓存键的唯一字符串。

  

其次,如果我的缓存包含许多相同类型的对象,即OrderResponse,我可以删除给定类型的所有项吗?

不,每个CacheProvider都不知道缓存的内容,缓存失效逻辑由客户端应用程序来管理。

  

否则,如果我修改了一个订单,我将不知道要删除哪个缓存对象。

是的,在这种情况下,您必须放置到期,以使其自身过期或使用底层缓存提供程序的任何高级功能(如果它们支持它)。例如。如果您使用MemoryCacheClient支持通配符API:

 cache.RemoveByPattern("cache:Orders:*");
 cache.RemoveByRegex("cache:Orders:.*);

因此,如果使用相同的前缀按层次结构构建密钥,则可以使用单个通配符命令使所有相关的高速缓存无效。