0

我正在尝试在 WebApi 应用程序中启用 RavenDB Aggressive Caching,以便在更大的应用程序中使用单个操作方法。

为了实现这一点,我创建了一个动作过滤器属性,该属性获取IDocumentSession, 并OnActionExecuting调用该方法以启用 15 分钟的积极缓存。然后,在 中OnActionexecuted,我呼吁DisableAggressiveCaching()同一个会话。

简而言之,这导致了一些相当奇怪的行为。在调用使用积极缓存的操作方法之后,对其他操作方法的后续请求,无论如何都不依赖缓存(它们发出完全不同的请求),最终得到一个15 分钟IDocumentSessionAggressiveCacheDuration时间。这种情况发生的频率似乎与之前调用缓存操作方法的次数成正比。我应该补充一点,我正在为 DI 使用 StructureMap,使用IDocumentStore单例,并注入 HttpContextScoped IDocumentSession。我已经确认每个请求都注入了一个新的 IDocumentSession,但其中一些已经启用了缓存。

一些代码可以尝试进一步详细说明......

国际奥委会 - RavenRegistry

var documentStore = new DocumentStore {ConnectionStringName = "RavenDB"};

documentStore.Initialize();

For<IDocumentStore>().Singleton().Use(documentStore);
For<IDocumentSession>().HttpContextScoped().Use(x =>
{
    var store = x.GetInstance<IDocumentStore>();
    var session =  store.OpenSession();
    return session;
});

AggressivelyCache属性

public class AggressivelyCacheAttribute : ActionFilterAttribute
{
    private IDocumentSession _documentSession;

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        base.OnActionExecuting(actionContext);

        _documentSession = actionContext.Request.GetDependencyScope()
            .GetService(typeof(IDocumentSession)) as IDocumentSession;

        _documentSession.Advanced.DocumentStore
            .AggressivelyCacheFor(TimeSpan.FromMinutes(15));
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);
        _documentSession.Advanced.DocumentStore.DisableAggressiveCaching();
    }
}

IDocumentSession然后在管道中稍后使用相同的方法查询数据库,其结果被缓存。

在随后的请求中,在属性不存在的方法上,注入IDocumentSession的缓存设置为 15 分钟。为什么会这样?

我在网上看到的唯一示例是在 using 语句中使用缓存创建会话的位置。这是使用积极缓存的唯一“安全”方式,还是可以做我正在尝试的事情?如果是这样,怎么做?

4

1 回答 1

1

基于Ayende 的博客平台代码,你需要在你的过滤器类中有一个引用:

private IDisposable _cachingHandle;

然后,当您进行缓存声明时,将结果分配给:

_cachingHandle  = _documentSession.Advanced.DocumentStore
    .AggressivelyCacheFor(TimeSpan.FromMinutes(15));

然后在你的执行中,

if(_cachingHandle != null)
    _cachingHandle.Dispose();

那应该停止不需要的缓存。

于 2012-11-10T05:34:47.363 回答