Hooking up StepExecutor/StepQueue into the recipe manager.

--HG--
branch : recipe
This commit is contained in:
Suha Can
2011-02-14 18:01:37 -08:00
parent 8ddb5b55b6
commit d3e4c2ad68
8 changed files with 81 additions and 19 deletions

View File

@@ -63,6 +63,8 @@ namespace Orchard.Tests.Modules.Recipes.Services {
_folders = new ModuleFolders(new[] { _tempFolderName }, new StubCacheManager(), new StubWebSiteFolder());
builder.RegisterType<RecipeManager>().As<IRecipeManager>();
builder.RegisterType<RecipeHarvester>().As<IRecipeHarvester>();
builder.RegisterType<RecipeStepExecutor>().As<IRecipeStepExecutor>();
builder.RegisterType<RecipeStepQueue>().As<IRecipeStepQueue>().InstancePerLifetimeScope();
builder.RegisterType<ExtensionManager>().As<IExtensionManager>();
builder.RegisterType<StubCacheManager>().As<ICacheManager>();
builder.RegisterInstance(_folders).As<IExtensionFolders>();

View File

@@ -63,6 +63,8 @@
<Compile Include="Services\RecipeHarvester.cs" />
<Compile Include="Services\RecipeManager.cs" />
<Compile Include="Services\RecipeParser.cs" />
<Compile Include="Services\RecipeStepExecutor.cs" />
<Compile Include="Services\RecipeStepQueue.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Orchard\Orchard.Framework.csproj">

View File

@@ -1,15 +1,16 @@
using System;
using System.Collections.Generic;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Recipes.Models;
namespace Orchard.Recipes.Services {
public class RecipeManager : IRecipeManager {
private readonly IEnumerable<IRecipeHandler> _recipeHandlers;
private readonly IRecipeStepQueue _recipeStepQueue;
private readonly IRecipeStepExecutor _recipeStepExecutor;
public RecipeManager(IEnumerable<IRecipeHandler> recipeHandlers) {
_recipeHandlers = recipeHandlers;
public RecipeManager(IRecipeStepQueue recipeStepQueue, IRecipeStepExecutor recipeStepExecutor) {
_recipeStepQueue = recipeStepQueue;
_recipeStepExecutor = recipeStepExecutor;
Logger = NullLogger.Instance;
T = NullLocalizer.Instance;
@@ -23,24 +24,15 @@ namespace Orchard.Recipes.Services {
return;
var executionId = Guid.NewGuid().ToString("n");
var recipeContext = new RecipeContext { Recipe = recipe };
// TODO: Run each step inside a transaction boundary.
// TODO: Enqueue steps for the step executor.
foreach (var recipeStep in recipe.RecipeSteps) {
recipeContext.RecipeStep = recipeStep;
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);
}
_recipeStepQueue.Enqueue(recipeStep, executionId);
}
// 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);
while (_recipeStepExecutor.ExecuteNextStep()) {}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -1,6 +1,5 @@
namespace Orchard.Recipes.Models {
public class RecipeContext {
public Recipe Recipe { get; set; }
public RecipeStep RecipeStep { get; set; }
public bool Executed { get; set; }
}

View File

@@ -1,7 +1,7 @@
using Orchard.Recipes.Models;
namespace Orchard.Recipes.Services {
public interface IRecipeJournal {
public interface IRecipeJournal : IDependency {
void StartExecution(string executionId);
void ExecutionComplete(string executionId);
void ExecutionFailed(string executionId);

View File

@@ -2,7 +2,7 @@
using Orchard.Recipes.Models;
namespace Orchard.Recipes.Services {
public interface IRecipeStepQueue : IDependency {
public interface IRecipeStepQueue : ISingletonDependency {
void Enqueue(RecipeStep step, string executionId);
Tuple<RecipeStep, string> Dequeue();
}