Fixing content type records caching

When a content type is created during a rolled back transaction, the cache
would hold a wrong id.

--HG--
branch : 1.x
extra : rebase_source : 756907c69eb0ce5f1f66a6ed204841fdab24cfd1
This commit is contained in:
Sebastien Ros 2013-06-28 17:21:10 -07:00
parent 6278e39746
commit 52f43ce80e
16 changed files with 35 additions and 3 deletions

View File

@ -32,6 +32,7 @@ namespace Orchard.Core.Tests.Body {
public override void Register(ContainerBuilder builder) { public override void Register(ContainerBuilder builder) {
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object); builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
builder.RegisterInstance(new Mock<ITransactionManager>().Object); builder.RegisterInstance(new Mock<ITransactionManager>().Object);

View File

@ -51,6 +51,7 @@ namespace Orchard.Core.Tests.Common.Providers {
public override void Register(ContainerBuilder builder) { public override void Register(ContainerBuilder builder) {
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterType<TestHandler>().As<IContentHandler>(); builder.RegisterType<TestHandler>().As<IContentHandler>();
builder.RegisterType<CommonPartHandler>().As<IContentHandler>(); builder.RegisterType<CommonPartHandler>().As<IContentHandler>();

View File

@ -38,6 +38,7 @@ namespace Orchard.Core.Tests.Scheduling {
builder.RegisterInstance(new Mock<ITransactionManager>().Object); builder.RegisterInstance(new Mock<ITransactionManager>().Object);
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterType<DefaultShapeTableManager>().As<IShapeTableManager>(); builder.RegisterType<DefaultShapeTableManager>().As<IShapeTableManager>();
builder.RegisterType<ShapeTableLocator>().As<IShapeTableLocator>(); builder.RegisterType<ShapeTableLocator>().As<IShapeTableLocator>();

View File

@ -40,6 +40,7 @@ namespace Orchard.Core.Tests.Scheduling {
public override void Register(ContainerBuilder builder) { public override void Register(ContainerBuilder builder) {
builder.RegisterInstance(_mockServices.Object); builder.RegisterInstance(_mockServices.Object);
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterType<DefaultShapeTableManager>().As<IShapeTableManager>(); builder.RegisterType<DefaultShapeTableManager>().As<IShapeTableManager>();

View File

@ -39,6 +39,7 @@ namespace Orchard.Tests.Modules.Comments.Services {
builder.RegisterType<CommentService>().As<ICommentService>(); builder.RegisterType<CommentService>().As<ICommentService>();
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object); builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
builder.RegisterInstance(new Mock<ITransactionManager>().Object); builder.RegisterInstance(new Mock<ITransactionManager>().Object);

View File

@ -67,6 +67,7 @@ namespace Orchard.Tests.Modules.Indexing {
builder.RegisterType<IndexingTaskManager>().As<IIndexingTaskManager>(); builder.RegisterType<IndexingTaskManager>().As<IIndexingTaskManager>();
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(_contentDefinitionManager.Object); builder.RegisterInstance(_contentDefinitionManager.Object);
builder.RegisterInstance(new Mock<IContentDisplay>().Object); builder.RegisterInstance(new Mock<IContentDisplay>().Object);

View File

@ -39,6 +39,7 @@ namespace Orchard.Tests.Modules.Tags.Services {
builder.RegisterType<OrchardServices>().As<IOrchardServices>(); builder.RegisterType<OrchardServices>().As<IOrchardServices>();
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)); builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
} }

View File

@ -74,6 +74,7 @@ namespace Orchard.Tests.Modules.Users.Services {
builder.RegisterType<DefaultContentQuery>().As<IContentQuery>(); builder.RegisterType<DefaultContentQuery>().As<IContentQuery>();
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType(typeof(SettingsFormatter)).As<ISettingsFormatter>(); builder.RegisterType(typeof(SettingsFormatter)).As<ISettingsFormatter>();
builder.RegisterType<ContentDefinitionManager>().As<IContentDefinitionManager>(); builder.RegisterType<ContentDefinitionManager>().As<IContentDefinitionManager>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();

View File

@ -85,6 +85,7 @@ namespace Orchard.Tests.Modules.Users.Services {
builder.RegisterType<DefaultContentQuery>().As<IContentQuery>(); builder.RegisterType<DefaultContentQuery>().As<IContentQuery>();
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType(typeof(SettingsFormatter)).As<ISettingsFormatter>(); builder.RegisterType(typeof(SettingsFormatter)).As<ISettingsFormatter>();
builder.RegisterType<ContentDefinitionManager>().As<IContentDefinitionManager>(); builder.RegisterType<ContentDefinitionManager>().As<IContentDefinitionManager>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();

View File

@ -90,6 +90,7 @@ namespace Orchard.Tests.Modules.Widgets.Services {
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object); builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
builder.RegisterInstance(new Mock<ITransactionManager>().Object); builder.RegisterInstance(new Mock<ITransactionManager>().Object);

View File

@ -48,6 +48,7 @@ namespace Orchard.Tests.ContentManagement {
builder.RegisterModule(new ContentModule()); builder.RegisterModule(new ContentModule());
builder.RegisterType<DefaultContentManager>().As<IContentManager>().SingleInstance(); builder.RegisterType<DefaultContentManager>().As<IContentManager>().SingleInstance();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object); builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);

View File

@ -61,6 +61,7 @@ namespace Orchard.Tests.ContentManagement {
builder.RegisterType<DefaultContentQuery>().As<IContentQuery>(); builder.RegisterType<DefaultContentQuery>().As<IContentQuery>();
builder.RegisterType<DefaultContentManager>().As<IContentManager>(); builder.RegisterType<DefaultContentManager>().As<IContentManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(_contentDefinitionManager.Object); builder.RegisterInstance(_contentDefinitionManager.Object);
builder.RegisterInstance(new Mock<IContentDisplay>().Object); builder.RegisterInstance(new Mock<IContentDisplay>().Object);

View File

@ -47,6 +47,7 @@ namespace Orchard.Tests.ContentManagement {
builder.RegisterModule(new ContentModule()); builder.RegisterModule(new ContentModule());
builder.RegisterType<DefaultContentManager>().As<IContentManager>().SingleInstance(); builder.RegisterType<DefaultContentManager>().As<IContentManager>().SingleInstance();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object); builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
builder.RegisterInstance(new Mock<IContentDisplay>().Object); builder.RegisterInstance(new Mock<IContentDisplay>().Object);

View File

@ -50,6 +50,7 @@ namespace Orchard.Tests.ContentManagement {
builder.RegisterModule(new ContentModule()); builder.RegisterModule(new ContentModule());
builder.RegisterType<DefaultContentManager>().As<IContentManager>().SingleInstance(); builder.RegisterType<DefaultContentManager>().As<IContentManager>().SingleInstance();
builder.RegisterType<StubCacheManager>().As<ICacheManager>(); builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterType<Signals>().As<ISignals>();
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>(); builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object); builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
builder.RegisterInstance(new Mock<IContentDisplay>().Object); builder.RegisterInstance(new Mock<IContentDisplay>().Object);

View File

@ -56,7 +56,7 @@
<td> <td>
@Html.ActionLink(T("Properties").ToString(), "Edit", new { Area = "Contents", id = entry.ImageProfileId, returnurl = HttpContext.Current.Request.RawUrl }) | @Html.ActionLink(T("Properties").ToString(), "Edit", new { Area = "Contents", id = entry.ImageProfileId, returnurl = HttpContext.Current.Request.RawUrl }) |
@Html.ActionLink(T("Edit").ToString(), "Edit", new { id = entry.ImageProfileId }) | @Html.ActionLink(T("Edit").ToString(), "Edit", new { id = entry.ImageProfileId }) |
@Html.ActionLink(T("Delete").ToString(), "Delete", new { id = entry.ImageProfileId }, new { itemprop = "RemoveUrl UnsafeUrl" }) | @Html.ActionLink(T("Delete").ToString(), "Delete", new { id = entry.ImageProfileId }, new { itemprop = "RemoveUrl UnsafeUrl" })
@*@Html.ActionLink(T("Preview").ToString(), "Preview", new { id = entry.ImageProfileId })*@ @*@Html.ActionLink(T("Preview").ToString(), "Preview", new { id = entry.ImageProfileId })*@
</td> </td>
</tr> </tr>

View File

@ -34,6 +34,7 @@ namespace Orchard.ContentManagement {
private readonly Lazy<ISessionLocator> _sessionLocator; private readonly Lazy<ISessionLocator> _sessionLocator;
private readonly Lazy<IEnumerable<IContentHandler>> _handlers; private readonly Lazy<IEnumerable<IContentHandler>> _handlers;
private readonly Lazy<IEnumerable<IIdentityResolverSelector>> _identityResolverSelectors; private readonly Lazy<IEnumerable<IIdentityResolverSelector>> _identityResolverSelectors;
private readonly ISignals _signals;
private const string Published = "Published"; private const string Published = "Published";
private const string Draft = "Draft"; private const string Draft = "Draft";
@ -49,7 +50,8 @@ namespace Orchard.ContentManagement {
Lazy<IContentDisplay> contentDisplay, Lazy<IContentDisplay> contentDisplay,
Lazy<ISessionLocator> sessionLocator, Lazy<ISessionLocator> sessionLocator,
Lazy<IEnumerable<IContentHandler>> handlers, Lazy<IEnumerable<IContentHandler>> handlers,
Lazy<IEnumerable<IIdentityResolverSelector>> identityResolverSelectors) { Lazy<IEnumerable<IIdentityResolverSelector>> identityResolverSelectors,
ISignals signals) {
_context = context; _context = context;
_contentTypeRepository = contentTypeRepository; _contentTypeRepository = contentTypeRepository;
_contentItemRepository = contentItemRepository; _contentItemRepository = contentItemRepository;
@ -58,6 +60,7 @@ namespace Orchard.ContentManagement {
_cacheManager = cacheManager; _cacheManager = cacheManager;
_contentManagerSession = contentManagerSession; _contentManagerSession = contentManagerSession;
_identityResolverSelectors = identityResolverSelectors; _identityResolverSelectors = identityResolverSelectors;
_signals = signals;
_handlers = handlers; _handlers = handlers;
_contentDisplay = contentDisplay; _contentDisplay = contentDisplay;
_sessionLocator = sessionLocator; _sessionLocator = sessionLocator;
@ -720,6 +723,8 @@ namespace Orchard.ContentManagement {
private ContentTypeRecord AcquireContentTypeRecord(string contentType) { private ContentTypeRecord AcquireContentTypeRecord(string contentType) {
var contentTypeId = _cacheManager.Get(contentType + "_Record", ctx => { var contentTypeId = _cacheManager.Get(contentType + "_Record", ctx => {
ctx.Monitor(_signals.When(contentType + "_Record"));
var contentTypeRecord = _contentTypeRepository.Get(x => x.Name == contentType); var contentTypeRecord = _contentTypeRepository.Get(x => x.Name == contentType);
if (contentTypeRecord == null) { if (contentTypeRecord == null) {
@ -731,7 +736,20 @@ namespace Orchard.ContentManagement {
return contentTypeRecord.Id; return contentTypeRecord.Id;
}); });
return _contentTypeRepository.Get(contentTypeId); // There is a case when a content type record is created locally but the transaction is actually
// cancelled. In this case we are caching an Id which is none existent, or might represent another
// content type. Thus we need to ensure that the cache is valid, or invalidate it and retrieve it
// another time.
var result = _contentTypeRepository.Get(contentTypeId);
if (result != null && result.Name.Equals(contentType, StringComparison.OrdinalIgnoreCase) ) {
return result;
}
// invalidate the cache entry and load it again
_signals.Trigger(contentType + "_Record");
return AcquireContentTypeRecord(contentType);
} }
public void Index(ContentItem contentItem, IDocumentIndex documentIndex) { public void Index(ContentItem contentItem, IDocumentIndex documentIndex) {