mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Hooking up StepExecutor/StepQueue into the recipe manager.
--HG-- branch : recipe
This commit is contained in:
@@ -63,6 +63,8 @@ namespace Orchard.Tests.Modules.Recipes.Services {
|
|||||||
_folders = new ModuleFolders(new[] { _tempFolderName }, new StubCacheManager(), new StubWebSiteFolder());
|
_folders = new ModuleFolders(new[] { _tempFolderName }, new StubCacheManager(), new StubWebSiteFolder());
|
||||||
builder.RegisterType<RecipeManager>().As<IRecipeManager>();
|
builder.RegisterType<RecipeManager>().As<IRecipeManager>();
|
||||||
builder.RegisterType<RecipeHarvester>().As<IRecipeHarvester>();
|
builder.RegisterType<RecipeHarvester>().As<IRecipeHarvester>();
|
||||||
|
builder.RegisterType<RecipeStepExecutor>().As<IRecipeStepExecutor>();
|
||||||
|
builder.RegisterType<RecipeStepQueue>().As<IRecipeStepQueue>().InstancePerLifetimeScope();
|
||||||
builder.RegisterType<ExtensionManager>().As<IExtensionManager>();
|
builder.RegisterType<ExtensionManager>().As<IExtensionManager>();
|
||||||
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
|
||||||
builder.RegisterInstance(_folders).As<IExtensionFolders>();
|
builder.RegisterInstance(_folders).As<IExtensionFolders>();
|
||||||
|
|||||||
@@ -63,6 +63,8 @@
|
|||||||
<Compile Include="Services\RecipeHarvester.cs" />
|
<Compile Include="Services\RecipeHarvester.cs" />
|
||||||
<Compile Include="Services\RecipeManager.cs" />
|
<Compile Include="Services\RecipeManager.cs" />
|
||||||
<Compile Include="Services\RecipeParser.cs" />
|
<Compile Include="Services\RecipeParser.cs" />
|
||||||
|
<Compile Include="Services\RecipeStepExecutor.cs" />
|
||||||
|
<Compile Include="Services\RecipeStepQueue.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
using Orchard.Recipes.Models;
|
using Orchard.Recipes.Models;
|
||||||
|
|
||||||
namespace Orchard.Recipes.Services {
|
namespace Orchard.Recipes.Services {
|
||||||
public class RecipeManager : IRecipeManager {
|
public class RecipeManager : IRecipeManager {
|
||||||
private readonly IEnumerable<IRecipeHandler> _recipeHandlers;
|
private readonly IRecipeStepQueue _recipeStepQueue;
|
||||||
|
private readonly IRecipeStepExecutor _recipeStepExecutor;
|
||||||
|
|
||||||
public RecipeManager(IEnumerable<IRecipeHandler> recipeHandlers) {
|
public RecipeManager(IRecipeStepQueue recipeStepQueue, IRecipeStepExecutor recipeStepExecutor) {
|
||||||
_recipeHandlers = recipeHandlers;
|
_recipeStepQueue = recipeStepQueue;
|
||||||
|
_recipeStepExecutor = recipeStepExecutor;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
@@ -23,24 +24,15 @@ namespace Orchard.Recipes.Services {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var executionId = Guid.NewGuid().ToString("n");
|
var executionId = Guid.NewGuid().ToString("n");
|
||||||
var recipeContext = new RecipeContext { Recipe = recipe };
|
|
||||||
|
|
||||||
// TODO: Run each step inside a transaction boundary.
|
// TODO: Run each step inside a transaction boundary.
|
||||||
// TODO: Enqueue steps for the step executor.
|
|
||||||
foreach (var recipeStep in recipe.RecipeSteps) {
|
foreach (var recipeStep in recipe.RecipeSteps) {
|
||||||
recipeContext.RecipeStep = recipeStep;
|
_recipeStepQueue.Enqueue(recipeStep, executionId);
|
||||||
recipeContext.Executed = false;
|
|
||||||
foreach (var recipeHandler in _recipeHandlers) {
|
|
||||||
recipeHandler.ExecuteRecipeStep(recipeContext);
|
|
||||||
}
|
|
||||||
if (!recipeContext.Executed) {
|
|
||||||
Logger.Error("Could not execute recipe step '{0}' because the recipe handler was not found.", recipeContext.RecipeStep.Name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: figure out shell settings and shell descriptor for processing engine to run under
|
// TODO: figure out shell settings and shell descriptor for processing engine to run under
|
||||||
|
// Use an event handler instead of directly calling the step executor.
|
||||||
// _processingEngine.AddTask(null, null, "IRecipeStepEvents_DoWork", null);
|
// _processingEngine.AddTask(null, null, "IRecipeStepEvents_DoWork", null);
|
||||||
|
while (_recipeStepExecutor.ExecuteNextStep()) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Localization;
|
||||||
|
using Orchard.Logging;
|
||||||
|
using Orchard.Recipes.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Recipes.Services {
|
||||||
|
public class RecipeStepExecutor : IRecipeStepExecutor {
|
||||||
|
private readonly IRecipeStepQueue _recipeStepQueue;
|
||||||
|
private readonly IEnumerable<IRecipeHandler> _recipeHandlers;
|
||||||
|
|
||||||
|
public RecipeStepExecutor(IRecipeStepQueue recipeStepQueue, IEnumerable<IRecipeHandler> recipeHandlers) {
|
||||||
|
_recipeStepQueue = recipeStepQueue;
|
||||||
|
_recipeHandlers = recipeHandlers;
|
||||||
|
|
||||||
|
Logger = NullLogger.Instance;
|
||||||
|
T = NullLocalizer.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Localizer T { get; set; }
|
||||||
|
ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
public bool ExecuteNextStep() {
|
||||||
|
var recipeStepWorkItem = _recipeStepQueue.Dequeue();
|
||||||
|
if (recipeStepWorkItem == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var recipeContext = new RecipeContext {RecipeStep = recipeStepWorkItem.Item1, Executed = false};
|
||||||
|
foreach (var recipeHandler in _recipeHandlers) {
|
||||||
|
recipeHandler.ExecuteRecipeStep(recipeContext);
|
||||||
|
}
|
||||||
|
if (!recipeContext.Executed) {
|
||||||
|
Logger.Error("Could not execute recipe step '{0}' because the recipe handler was not found.", recipeContext.RecipeStep.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.Localization;
|
||||||
|
using Orchard.Logging;
|
||||||
|
using Orchard.Recipes.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Recipes.Services {
|
||||||
|
public class RecipeStepQueue : IRecipeStepQueue {
|
||||||
|
// placeholder to be dropped in favor of an IAppDataFolder based impl
|
||||||
|
private readonly Queue<Tuple<RecipeStep, string>> _stepQueue;
|
||||||
|
|
||||||
|
public RecipeStepQueue() {
|
||||||
|
_stepQueue = new Queue<Tuple<RecipeStep, string>>();
|
||||||
|
Logger = NullLogger.Instance;
|
||||||
|
T = NullLocalizer.Instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Localizer T { get; set; }
|
||||||
|
ILogger Logger { get; set; }
|
||||||
|
|
||||||
|
public void Enqueue(RecipeStep step, string executionId) {
|
||||||
|
_stepQueue.Enqueue(new Tuple<RecipeStep, string>(step, executionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tuple<RecipeStep, string> Dequeue() {
|
||||||
|
return _stepQueue.Count > 0 ? _stepQueue.Dequeue() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
namespace Orchard.Recipes.Models {
|
namespace Orchard.Recipes.Models {
|
||||||
public class RecipeContext {
|
public class RecipeContext {
|
||||||
public Recipe Recipe { get; set; }
|
|
||||||
public RecipeStep RecipeStep { get; set; }
|
public RecipeStep RecipeStep { get; set; }
|
||||||
public bool Executed { get; set; }
|
public bool Executed { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Orchard.Recipes.Models;
|
using Orchard.Recipes.Models;
|
||||||
|
|
||||||
namespace Orchard.Recipes.Services {
|
namespace Orchard.Recipes.Services {
|
||||||
public interface IRecipeJournal {
|
public interface IRecipeJournal : IDependency {
|
||||||
void StartExecution(string executionId);
|
void StartExecution(string executionId);
|
||||||
void ExecutionComplete(string executionId);
|
void ExecutionComplete(string executionId);
|
||||||
void ExecutionFailed(string executionId);
|
void ExecutionFailed(string executionId);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using Orchard.Recipes.Models;
|
using Orchard.Recipes.Models;
|
||||||
|
|
||||||
namespace Orchard.Recipes.Services {
|
namespace Orchard.Recipes.Services {
|
||||||
public interface IRecipeStepQueue : IDependency {
|
public interface IRecipeStepQueue : ISingletonDependency {
|
||||||
void Enqueue(RecipeStep step, string executionId);
|
void Enqueue(RecipeStep step, string executionId);
|
||||||
Tuple<RecipeStep, string> Dequeue();
|
Tuple<RecipeStep, string> Dequeue();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user