mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Improved recipe import/reset execution by pausing sweep generator.
This prevents active background tasks from accessing tables that may no longer be there (in the case of a full site reset) by pausing the sweep generator. To ensure that the sweep generator is resumed after the recipe has been executed, a new ActivateSweepGeneratorStep is enqueued at the end of the recipe execution.
This commit is contained in:
@@ -4,14 +4,15 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Data;
|
||||||
using Orchard.Environment.Configuration;
|
using Orchard.Environment.Configuration;
|
||||||
using Orchard.Environment.Features;
|
|
||||||
using Orchard.ImportExport.Models;
|
using Orchard.ImportExport.Models;
|
||||||
using Orchard.ImportExport.Services;
|
using Orchard.ImportExport.Services;
|
||||||
using Orchard.ImportExport.ViewModels;
|
using Orchard.ImportExport.ViewModels;
|
||||||
using Orchard.Mvc;
|
using Orchard.Mvc;
|
||||||
using Orchard.Recipes.Models;
|
using Orchard.Recipes.Models;
|
||||||
using Orchard.Recipes.Services;
|
using Orchard.Recipes.Services;
|
||||||
|
using Orchard.Tasks;
|
||||||
using Orchard.UI.Notify;
|
using Orchard.UI.Notify;
|
||||||
|
|
||||||
namespace Orchard.ImportExport.Providers.ImportActions {
|
namespace Orchard.ImportExport.Providers.ImportActions {
|
||||||
@@ -19,30 +20,36 @@ namespace Orchard.ImportExport.Providers.ImportActions {
|
|||||||
private readonly IOrchardServices _orchardServices;
|
private readonly IOrchardServices _orchardServices;
|
||||||
private readonly ISetupService _setupService;
|
private readonly ISetupService _setupService;
|
||||||
private readonly ShellSettings _shellSettings;
|
private readonly ShellSettings _shellSettings;
|
||||||
private readonly IFeatureManager _featureManager;
|
|
||||||
private readonly IEnumerable<IRecipeExecutionStep> _recipeExecutionSteps;
|
private readonly IEnumerable<IRecipeExecutionStep> _recipeExecutionSteps;
|
||||||
private readonly IRecipeParser _recipeParser;
|
private readonly IRecipeParser _recipeParser;
|
||||||
private readonly IRecipeExecutor _recipeExecutor;
|
private readonly IRecipeExecutor _recipeExecutor;
|
||||||
private readonly IDatabaseManager _databaseManager;
|
private readonly IDatabaseManager _databaseManager;
|
||||||
|
private readonly ISweepGenerator _sweepGenerator;
|
||||||
|
private readonly IRecipeStepQueue _recipeStepQueue;
|
||||||
|
private readonly IRepository<RecipeStepResultRecord> _recipeStepResultRepository;
|
||||||
|
|
||||||
public ExecuteRecipeAction(
|
public ExecuteRecipeAction(
|
||||||
IOrchardServices orchardServices,
|
IOrchardServices orchardServices,
|
||||||
ISetupService setupService,
|
ISetupService setupService,
|
||||||
ShellSettings shellSettings,
|
ShellSettings shellSettings,
|
||||||
IFeatureManager featureManager,
|
|
||||||
IEnumerable<IRecipeExecutionStep> recipeExecutionSteps,
|
IEnumerable<IRecipeExecutionStep> recipeExecutionSteps,
|
||||||
IRecipeParser recipeParser,
|
IRecipeParser recipeParser,
|
||||||
IRecipeExecutor recipeExecutor,
|
IRecipeExecutor recipeExecutor,
|
||||||
IDatabaseManager databaseManager) {
|
IDatabaseManager databaseManager,
|
||||||
|
ISweepGenerator sweepGenerator,
|
||||||
|
IRecipeStepQueue recipeStepQueue,
|
||||||
|
IRepository<RecipeStepResultRecord> recipeStepResultRepository) {
|
||||||
|
|
||||||
_orchardServices = orchardServices;
|
_orchardServices = orchardServices;
|
||||||
_setupService = setupService;
|
_setupService = setupService;
|
||||||
_shellSettings = shellSettings;
|
_shellSettings = shellSettings;
|
||||||
_featureManager = featureManager;
|
|
||||||
_recipeExecutionSteps = recipeExecutionSteps;
|
_recipeExecutionSteps = recipeExecutionSteps;
|
||||||
_recipeParser = recipeParser;
|
_recipeParser = recipeParser;
|
||||||
_recipeExecutor = recipeExecutor;
|
_recipeExecutor = recipeExecutor;
|
||||||
_databaseManager = databaseManager;
|
_databaseManager = databaseManager;
|
||||||
|
_sweepGenerator = sweepGenerator;
|
||||||
|
_recipeStepQueue = recipeStepQueue;
|
||||||
|
_recipeStepResultRepository = recipeStepResultRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Name { get { return "ExecuteRecipe"; } }
|
public override string Name { get { return "ExecuteRecipe"; } }
|
||||||
@@ -144,13 +151,29 @@ namespace Orchard.ImportExport.Providers.ImportActions {
|
|||||||
// Sets the request timeout to 10 minutes to give enough time to execute custom recipes.
|
// Sets the request timeout to 10 minutes to give enough time to execute custom recipes.
|
||||||
_orchardServices.WorkContext.HttpContext.Server.ScriptTimeout = 600;
|
_orchardServices.WorkContext.HttpContext.Server.ScriptTimeout = 600;
|
||||||
|
|
||||||
|
// Suspend background task execution.
|
||||||
|
_sweepGenerator.Terminate();
|
||||||
|
|
||||||
|
// Import or setup using the specified recipe.
|
||||||
var executionId = ResetSite ? Setup(recipeDocument) : ExecuteRecipe(recipeDocument);
|
var executionId = ResetSite ? Setup(recipeDocument) : ExecuteRecipe(recipeDocument);
|
||||||
|
|
||||||
if(executionId == null) {
|
if(executionId == null) {
|
||||||
_orchardServices.Notifier.Warning(T("The recipe contained no steps. No work was scheduled."));
|
_orchardServices.Notifier.Warning(T("The recipe contained no steps. No work was scheduled."));
|
||||||
|
_sweepGenerator.Activate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resume background tasks once import/setup completes.
|
||||||
|
var recipe = _recipeParser.ParseRecipe(recipeDocument);
|
||||||
|
var activateSweepGeneratorStep = new RecipeStep(Guid.NewGuid().ToString("N"), recipe.Name, "ActivateSweepGenerator", new XElement("ActivateSweepGenerator"));
|
||||||
|
_recipeStepQueue.Enqueue(executionId, activateSweepGeneratorStep);
|
||||||
|
_recipeStepResultRepository.Create(new RecipeStepResultRecord {
|
||||||
|
ExecutionId = executionId,
|
||||||
|
RecipeName = recipe.Name,
|
||||||
|
StepId = activateSweepGeneratorStep.Id,
|
||||||
|
StepName = activateSweepGeneratorStep.Name
|
||||||
|
});
|
||||||
|
|
||||||
context.ExecutionId = executionId;
|
context.ExecutionId = executionId;
|
||||||
context.RecipeDocument = recipeDocument;
|
context.RecipeDocument = recipeDocument;
|
||||||
}
|
}
|
||||||
@@ -172,7 +195,9 @@ namespace Orchard.ImportExport.Providers.ImportActions {
|
|||||||
DropTenantDatabaseTables();
|
DropTenantDatabaseTables();
|
||||||
|
|
||||||
// Execute Setup.
|
// Execute Setup.
|
||||||
return _setupService.Setup(setupContext);
|
var executionId = _setupService.Setup(setupContext);
|
||||||
|
|
||||||
|
return executionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ExecuteRecipe(XDocument recipeDocument) {
|
private string ExecuteRecipe(XDocument recipeDocument) {
|
||||||
|
|||||||
@@ -91,6 +91,7 @@
|
|||||||
<Compile Include="Providers\Builders\ContentStep.cs" />
|
<Compile Include="Providers\Builders\ContentStep.cs" />
|
||||||
<Compile Include="Providers\Builders\RecipeMetadataStep.cs" />
|
<Compile Include="Providers\Builders\RecipeMetadataStep.cs" />
|
||||||
<Compile Include="Providers\Builders\SettingsStep.cs" />
|
<Compile Include="Providers\Builders\SettingsStep.cs" />
|
||||||
|
<Compile Include="Providers\Executors\ActivateSweepGeneratorStep.cs" />
|
||||||
<Compile Include="Providers\Executors\CommandStep.cs" />
|
<Compile Include="Providers\Executors\CommandStep.cs" />
|
||||||
<Compile Include="Providers\Executors\RecipesStep.cs" />
|
<Compile Include="Providers\Executors\RecipesStep.cs" />
|
||||||
<Compile Include="ViewModels\ContentExecutionStepViewModel.cs" />
|
<Compile Include="ViewModels\ContentExecutionStepViewModel.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using Orchard.Recipes.Models;
|
||||||
|
using Orchard.Recipes.Services;
|
||||||
|
using Orchard.Tasks;
|
||||||
|
|
||||||
|
namespace Orchard.Recipes.Providers.Executors {
|
||||||
|
public class ActivateSweepGeneratorStep : RecipeExecutionStep {
|
||||||
|
private readonly ISweepGenerator _sweepGenerator;
|
||||||
|
|
||||||
|
public ActivateSweepGeneratorStep(ISweepGenerator sweepGenerator, RecipeExecutionLogger logger)
|
||||||
|
: base(logger) {
|
||||||
|
_sweepGenerator = sweepGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Name { get { return "ActivateSweepGenerator"; } }
|
||||||
|
|
||||||
|
public override void Execute(RecipeExecutionContext context) {
|
||||||
|
_sweepGenerator.Activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user