Process all pending tasks at the end of the request

Instead of processing tasks asynchronously at the end of a request,
we process them synchronously, so that the behavior is more
deterministic.

--HG--
branch : dev
This commit is contained in:
Renaud Paquay
2010-12-04 14:11:18 -08:00
parent 3a4a4b7837
commit 5ab00ebabe
2 changed files with 26 additions and 22 deletions

View File

@@ -147,6 +147,8 @@ namespace Orchard.Environment {
}
private void DisposeShellContext() {
Logger.Information("Disposing active shell contexts");
if (_current != null) {
foreach (var shellContext in _current) {
shellContext.Shell.Terminate();
@@ -160,25 +162,14 @@ namespace Orchard.Environment {
BuildCurrent();
}
// the exit gate is temporary, until better control strategy is in place
private readonly ManualResetEvent _exitGate = new ManualResetEvent(true);
protected virtual void EndRequest() {
if (_processingEngine.AreTasksPending()) {
_exitGate.Reset();
ThreadPool.QueueUserWorkItem(state => {
// Synchronously process all pending tasks. It's safe to do this at this point
// of the pipeline, as the request transaction has been closed, so creating a new
// environment and transaction for these tasks will behave as expected.
while (_processingEngine.AreTasksPending()) {
_processingEngine.ExecuteNextTask();
if (!_processingEngine.AreTasksPending()) {
_exitGate.Set();
}
}
});
}
_exitGate.WaitOne(250);
}
void IShellSettingsManagerEventHandler.Saved(ShellSettings settings) {
DisposeShellContext();

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.Data;
using Orchard.Environment.Configuration;
using Orchard.Environment.ShellBuilders;
using Orchard.Environment.Descriptor.Models;
@@ -69,13 +70,25 @@ namespace Orchard.Environment.State {
var shellContext = _shellContextFactory.CreateDescribedContext(entry.ShellSettings, entry.ShellDescriptor);
using (shellContext.LifetimeScope) {
using (var standaloneEnvironment = shellContext.LifetimeScope.CreateWorkContextScope()) {
var eventBus = standaloneEnvironment.Resolve<IEventBus>();
ITransactionManager transactionManager;
if (!standaloneEnvironment.TryResolve(out transactionManager))
transactionManager = null;
try {
var eventBus = standaloneEnvironment.Resolve<IEventBus>();
Logger.Information("Executing event {0} in process {1} for shell {2}",
entry.MessageName,
entry.ProcessId,
entry.ShellSettings.Name);
eventBus.NotifyFailFast(entry.MessageName, entry.EventData);
eventBus.Notify(entry.MessageName, entry.EventData);
}
catch {
// any database changes in this using(env) scope are invalidated
if (transactionManager != null)
transactionManager.Cancel();
throw;
}
}
}
}