mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-01-19 17:51:45 +08:00
When a content type gets modified, its items will get re-indexed by a JobsQueue job instead of a custom queue-like implementation. Fixes #4729.
Since this adds a new dependency to Orchard.Indexing it requires #3132 to be fixed.
This commit is contained in:
@@ -20,18 +20,7 @@ namespace Orchard.Indexing {
|
|||||||
.Column<int>("ContentItemRecord_id")
|
.Column<int>("ContentItemRecord_id")
|
||||||
);
|
);
|
||||||
|
|
||||||
SchemaBuilder.CreateTable("IndexTaskBatchRecord",
|
return 4;
|
||||||
table => table
|
|
||||||
.Column<int>("Id", column => column.PrimaryKey().Identity())
|
|
||||||
.Column<int>("BatchStartIndex")
|
|
||||||
.Column<string>("ContentType")
|
|
||||||
)
|
|
||||||
.AlterTable("IndexTaskBatchRecord",
|
|
||||||
table =>
|
|
||||||
table.CreateIndex("IDX_ContentType", "ContentType")
|
|
||||||
);
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int UpdateFrom1() {
|
public int UpdateFrom1() {
|
||||||
@@ -49,18 +38,16 @@ namespace Orchard.Indexing {
|
|||||||
|
|
||||||
public int UpdateFrom2() {
|
public int UpdateFrom2() {
|
||||||
|
|
||||||
SchemaBuilder.CreateTable("IndexTaskBatchRecord",
|
// A table for a custom job implementation was here, but since we use JobsQueue that table is deprecated.
|
||||||
table => table
|
|
||||||
.Column<int>("Id", column => column.PrimaryKey().Identity())
|
|
||||||
.Column<int>("BatchStartIndex")
|
|
||||||
.Column<string>("ContentType")
|
|
||||||
)
|
|
||||||
.AlterTable("IndexTaskBatchRecord",
|
|
||||||
table =>
|
|
||||||
table.CreateIndex("IDX_ContentType", "ContentType")
|
|
||||||
);
|
|
||||||
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int UpdateFrom3() {
|
||||||
|
|
||||||
|
SchemaBuilder.DropTable("IndexTaskBatchRecord");
|
||||||
|
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,3 +7,4 @@ OrchardVersion: 1.9
|
|||||||
Description: The Indexing module enables the site to be indexed. The index generated by this module can then be used by the search module to provide an integrated full-text search experience to a web site.
|
Description: The Indexing module enables the site to be indexed. The index generated by this module can then be used by the search module to provide an integrated full-text search experience to a web site.
|
||||||
FeatureDescription: Indexing infrastructure. Requires an index implementation like the Lucene module.
|
FeatureDescription: Indexing infrastructure. Requires an index implementation like the Lucene module.
|
||||||
Category: Search
|
Category: Search
|
||||||
|
Dependencies: Orchard.JobsQueue
|
||||||
|
|||||||
@@ -78,9 +78,8 @@
|
|||||||
<Compile Include="Models\IndexSettings.cs">
|
<Compile Include="Models\IndexSettings.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Models\IndexTaskBatchRecord.cs" />
|
<Compile Include="Services\CreateUpdateIndexTaskService.cs" />
|
||||||
<Compile Include="Services\IIndexTaskBatchManagementService.cs" />
|
<Compile Include="Services\ICreateUpdateIndexTaskService.cs" />
|
||||||
<Compile Include="Services\IndexTaskBatchManagementService.cs" />
|
|
||||||
<Compile Include="Services\UpdateIndexScheduler.cs" />
|
<Compile Include="Services\UpdateIndexScheduler.cs" />
|
||||||
<Compile Include="Services\IIndexingTaskExecutor.cs" />
|
<Compile Include="Services\IIndexingTaskExecutor.cs" />
|
||||||
<Compile Include="Services\IUpdateIndexScheduler.cs" />
|
<Compile Include="Services\IUpdateIndexScheduler.cs" />
|
||||||
@@ -94,7 +93,6 @@
|
|||||||
<Compile Include="Services\IndexingService.cs" />
|
<Compile Include="Services\IndexingService.cs" />
|
||||||
<Compile Include="Settings\EditorEvents.cs" />
|
<Compile Include="Settings\EditorEvents.cs" />
|
||||||
<Compile Include="Settings\FieldIndexing.cs" />
|
<Compile Include="Settings\FieldIndexing.cs" />
|
||||||
<Compile Include="Services\CreateUpdateIndexTaskBackgroundTask.cs" />
|
|
||||||
<Compile Include="Settings\TypeIndexing.cs" />
|
<Compile Include="Settings\TypeIndexing.cs" />
|
||||||
<Compile Include="ViewModels\IndexViewModel.cs" />
|
<Compile Include="ViewModels\IndexViewModel.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -102,12 +100,14 @@
|
|||||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||||
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
|
<Project>{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}</Project>
|
||||||
<Name>Orchard.Framework</Name>
|
<Name>Orchard.Framework</Name>
|
||||||
<Private>false</Private>
|
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
|
<ProjectReference Include="..\..\Core\Orchard.Core.csproj">
|
||||||
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
|
<Project>{9916839C-39FC-4CEB-A5AF-89CA7E87119F}</Project>
|
||||||
<Name>Orchard.Core</Name>
|
<Name>Orchard.Core</Name>
|
||||||
<Private>false</Private>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\Orchard.JobsQueue\Orchard.JobsQueue.csproj">
|
||||||
|
<Project>{085948ff-0e9b-4a9a-b564-f8b8b4bdddbc}</Project>
|
||||||
|
<Name>Orchard.JobsQueue</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -146,11 +146,11 @@
|
|||||||
</FlavorProperties>
|
</FlavorProperties>
|
||||||
</VisualStudio>
|
</VisualStudio>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Events;
|
||||||
|
using Orchard.Tasks.Indexing;
|
||||||
|
|
||||||
|
namespace Orchard.Indexing.Services {
|
||||||
|
public interface IJobsQueueService : IEventHandler {
|
||||||
|
void Enqueue(string message, object parameters, int priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreateUpdateIndexTaskService : ICreateUpdateIndexTaskService {
|
||||||
|
private readonly IContentManager _contentManager;
|
||||||
|
private readonly IJobsQueueService _jobsQueueService;
|
||||||
|
private readonly IIndexingTaskManager _indexingTaskManager;
|
||||||
|
|
||||||
|
private const int BatchSize = 50;
|
||||||
|
public const int JobPriority = 10;
|
||||||
|
|
||||||
|
public CreateUpdateIndexTaskService(IContentManager contentManager, IIndexingTaskManager indexingTaskManager, IJobsQueueService jobsQueueService) {
|
||||||
|
_jobsQueueService = jobsQueueService;
|
||||||
|
_indexingTaskManager = indexingTaskManager;
|
||||||
|
_contentManager = contentManager;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateNextIndexingTaskBatch(string contentTypeName, string currentBatchIndex) {
|
||||||
|
var contentItems = _contentManager.Query(contentTypeName).Slice(int.Parse(currentBatchIndex), BatchSize).ToList();
|
||||||
|
|
||||||
|
foreach (var contentItem in contentItems) {
|
||||||
|
_indexingTaskManager.CreateUpdateIndexTask(contentItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentItems.Count == BatchSize) {
|
||||||
|
_jobsQueueService.Enqueue("ICreateUpdateIndexTaskService.CreateNextIndexingTaskBatch", new Dictionary<string, object> { { "contentTypeName", contentTypeName }, { "currentBatchIndex", (int.Parse(currentBatchIndex) + BatchSize).ToString() } }, JobPriority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using Orchard.Events;
|
||||||
|
|
||||||
|
namespace Orchard.Indexing.Services {
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the creation of indexing tasks in batches.
|
||||||
|
/// </summary>
|
||||||
|
public interface ICreateUpdateIndexTaskService : IEventHandler {
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the next set of indexing task batches, and renews itself with the next batch.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="contentTypeName">The content type name.</param>
|
||||||
|
/// <param name="currentBatchIndex">The current batch index. This must be string, because <see cref="DefaultOrchardEventBus"/> throws InvalidCastException if this is int.</param>
|
||||||
|
void CreateNextIndexingTaskBatch(string contentTypeName, string currentBatchIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,15 +9,15 @@ using Orchard.Indexing.Services;
|
|||||||
|
|
||||||
namespace Orchard.Indexing.Settings {
|
namespace Orchard.Indexing.Settings {
|
||||||
public class EditorEvents : ContentDefinitionEditorEventsBase {
|
public class EditorEvents : ContentDefinitionEditorEventsBase {
|
||||||
private readonly IIndexTaskBatchManagementService _indexTaskBatchManagementService;
|
private readonly IJobsQueueService _jobsQueueService;
|
||||||
|
|
||||||
|
public EditorEvents(IJobsQueueService jobsQueueService) {
|
||||||
|
_jobsQueueService = jobsQueueService;
|
||||||
|
}
|
||||||
|
|
||||||
private string _contentTypeName;
|
private string _contentTypeName;
|
||||||
private bool _tasksCreated;
|
private bool _tasksCreated;
|
||||||
|
|
||||||
public EditorEvents(IIndexTaskBatchManagementService indexTaskBatchManagementService) {
|
|
||||||
_indexTaskBatchManagementService = indexTaskBatchManagementService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<TemplateViewModel> TypeEditor(ContentTypeDefinition definition) {
|
public override IEnumerable<TemplateViewModel> TypeEditor(ContentTypeDefinition definition) {
|
||||||
var model = definition.Settings.GetModel<TypeIndexing>();
|
var model = definition.Settings.GetModel<TypeIndexing>();
|
||||||
_contentTypeName = definition.Name;
|
_contentTypeName = definition.Name;
|
||||||
@@ -33,7 +33,7 @@ namespace Orchard.Indexing.Settings {
|
|||||||
|
|
||||||
// create indexing tasks only if settings have changed
|
// create indexing tasks only if settings have changed
|
||||||
if (Clean(model.Indexes) != Clean(previous.Indexes)) {
|
if (Clean(model.Indexes) != Clean(previous.Indexes)) {
|
||||||
|
|
||||||
// if a an index is added, all existing content items need to be re-indexed
|
// if a an index is added, all existing content items need to be re-indexed
|
||||||
CreateIndexingTasks();
|
CreateIndexingTasks();
|
||||||
}
|
}
|
||||||
@@ -53,8 +53,8 @@ namespace Orchard.Indexing.Settings {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void CreateIndexingTasks() {
|
private void CreateIndexingTasks() {
|
||||||
if (!_tasksCreated) {
|
if (!_tasksCreated) {
|
||||||
// Creating tasks in batches is needed because editing content type settings for a type with many items causes OutOfMemoryException, see issue: https://github.com/OrchardCMS/Orchard/issues/4729
|
// Creating tasks with Jobs is needed because editing content type settings for a type with many items causes OutOfMemoryException, see issue: https://github.com/OrchardCMS/Orchard/issues/4729
|
||||||
_indexTaskBatchManagementService.RegisterContentType(_contentTypeName);
|
_jobsQueueService.Enqueue("ICreateUpdateIndexTaskService.CreateNextIndexingTaskBatch", new Dictionary<string, object> { { "contentTypeName", _contentTypeName }, { "currentBatchIndex", "0" } }, CreateUpdateIndexTaskService.JobPriority);
|
||||||
_tasksCreated = true;
|
_tasksCreated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,8 +65,8 @@ namespace Orchard.Indexing.Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<TemplateViewModel> PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) {
|
public override IEnumerable<TemplateViewModel> PartFieldEditorUpdate(ContentPartFieldDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||||
var previous = builder.Current.Settings.GetModel<FieldIndexing>();
|
var previous = builder.Current.Settings.GetModel<FieldIndexing>();
|
||||||
|
|
||||||
var model = new FieldIndexing();
|
var model = new FieldIndexing();
|
||||||
updateModel.TryUpdateModel(model, "FieldIndexing", null, null);
|
updateModel.TryUpdateModel(model, "FieldIndexing", null, null);
|
||||||
builder.WithSetting("FieldIndexing.Included", model.Included ? true.ToString() : null);
|
builder.WithSetting("FieldIndexing.Included", model.Included ? true.ToString() : null);
|
||||||
|
|||||||
Reference in New Issue
Block a user