mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Fixing random exceptions in Orchard.Workflows
--HG-- branch : 1.x
This commit is contained in:
@@ -43,7 +43,11 @@ namespace Orchard.Workflows.Models {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public object GetState(string key) {
|
public object GetState(string key) {
|
||||||
return GetState<object>(key);
|
if (State == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return State[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStateFor<T>(ActivityRecord record, string key, T value) {
|
public void SetStateFor<T>(ActivityRecord record, string key, T value) {
|
||||||
|
@@ -19,8 +19,9 @@ namespace Orchard.Workflows {
|
|||||||
builder.Add().DefineStyle("WorkflowsActivities-SendEmail").SetUrl("workflows-activity-sendemail.css").SetDependencies("WorkflowsAdmin");
|
builder.Add().DefineStyle("WorkflowsActivities-SendEmail").SetUrl("workflows-activity-sendemail.css").SetDependencies("WorkflowsAdmin");
|
||||||
builder.Add().DefineStyle("WorkflowsActivities-Timer").SetUrl("workflows-activity-timer.css").SetDependencies("WorkflowsAdmin");
|
builder.Add().DefineStyle("WorkflowsActivities-Timer").SetUrl("workflows-activity-timer.css").SetDependencies("WorkflowsAdmin");
|
||||||
builder.Add().DefineStyle("WorkflowsActivities-UserTask").SetUrl("workflows-activity-usertask.css").SetDependencies("WorkflowsAdmin");
|
builder.Add().DefineStyle("WorkflowsActivities-UserTask").SetUrl("workflows-activity-usertask.css").SetDependencies("WorkflowsAdmin");
|
||||||
|
|
||||||
builder.Add().DefineStyle("WorkflowsActivities").SetDependencies(
|
builder.Add().DefineStyle("WorkflowsActivities").SetUrl("workflows-activity.css")
|
||||||
|
.SetDependencies(
|
||||||
"WorkflowsActivities-Branch",
|
"WorkflowsActivities-Branch",
|
||||||
"WorkflowsActivities-ContentCreate",
|
"WorkflowsActivities-ContentCreate",
|
||||||
"WorkflowsActivities-ContentPublished",
|
"WorkflowsActivities-ContentPublished",
|
||||||
|
@@ -17,7 +17,6 @@ namespace Orchard.Workflows.Services {
|
|||||||
private readonly IRepository<ActivityRecord> _activityRepository;
|
private readonly IRepository<ActivityRecord> _activityRepository;
|
||||||
private readonly IRepository<WorkflowRecord> _workflowRepository;
|
private readonly IRepository<WorkflowRecord> _workflowRepository;
|
||||||
private readonly IRepository<AwaitingActivityRecord> _awaitingActivityRepository;
|
private readonly IRepository<AwaitingActivityRecord> _awaitingActivityRepository;
|
||||||
private readonly IRepository<WorkflowDefinitionRecord> _workflowDefinitionRepository;
|
|
||||||
private readonly ITokenizer _tokenizer;
|
private readonly ITokenizer _tokenizer;
|
||||||
|
|
||||||
public WorkflowManager(
|
public WorkflowManager(
|
||||||
@@ -25,13 +24,11 @@ namespace Orchard.Workflows.Services {
|
|||||||
IRepository<ActivityRecord> activityRepository,
|
IRepository<ActivityRecord> activityRepository,
|
||||||
IRepository<WorkflowRecord> workflowRepository,
|
IRepository<WorkflowRecord> workflowRepository,
|
||||||
IRepository<AwaitingActivityRecord> awaitingActivityRepository,
|
IRepository<AwaitingActivityRecord> awaitingActivityRepository,
|
||||||
IRepository<WorkflowDefinitionRecord> workflowDefinitionRepository,
|
|
||||||
ITokenizer tokenizer) {
|
ITokenizer tokenizer) {
|
||||||
_activitiesManager = activitiesManager;
|
_activitiesManager = activitiesManager;
|
||||||
_activityRepository = activityRepository;
|
_activityRepository = activityRepository;
|
||||||
_workflowRepository = workflowRepository;
|
_workflowRepository = workflowRepository;
|
||||||
_awaitingActivityRepository = awaitingActivityRepository;
|
_awaitingActivityRepository = awaitingActivityRepository;
|
||||||
_workflowDefinitionRepository = workflowDefinitionRepository;
|
|
||||||
_tokenizer = tokenizer;
|
_tokenizer = tokenizer;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
@@ -75,41 +72,6 @@ namespace Orchard.Workflows.Services {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var workflowContext = new WorkflowContext {
|
|
||||||
Content = target,
|
|
||||||
Tokens = tokens
|
|
||||||
};
|
|
||||||
|
|
||||||
// evaluate processing condition
|
|
||||||
awaitingActivities = awaitingActivities.Where(a => {
|
|
||||||
|
|
||||||
var activityContext = CreateActivityContext(a.ActivityRecord, tokens);
|
|
||||||
|
|
||||||
// check the condition
|
|
||||||
try {
|
|
||||||
return activity.CanExecute(workflowContext, activityContext);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Logger.Error("Error while evaluating an activity condition on {0}: {1}", name, e.ToString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
// evaluate processing condition
|
|
||||||
startedWorkflows = startedWorkflows.Where(a => {
|
|
||||||
|
|
||||||
var activityContext = CreateActivityContext(a, tokens);
|
|
||||||
|
|
||||||
// check the condition
|
|
||||||
try {
|
|
||||||
return activity.CanExecute(workflowContext, activityContext);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Logger.Error("Error while evaluating an activity condition on {0}: {1}", name, e.ToString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
// if no activity record is matching the event, do nothing
|
// if no activity record is matching the event, do nothing
|
||||||
if (!startedWorkflows.Any() && !awaitingActivities.Any()) {
|
if (!startedWorkflows.Any() && !awaitingActivities.Any()) {
|
||||||
return;
|
return;
|
||||||
@@ -117,11 +79,57 @@ namespace Orchard.Workflows.Services {
|
|||||||
|
|
||||||
// resume halted workflows
|
// resume halted workflows
|
||||||
foreach (var awaitingActivityRecord in awaitingActivities) {
|
foreach (var awaitingActivityRecord in awaitingActivities) {
|
||||||
|
var workflowContext = new WorkflowContext {
|
||||||
|
Content = target,
|
||||||
|
Tokens = tokens,
|
||||||
|
Record = awaitingActivityRecord.WorkflowRecord
|
||||||
|
};
|
||||||
|
|
||||||
|
var activityContext = CreateActivityContext(awaitingActivityRecord.ActivityRecord, tokens);
|
||||||
|
|
||||||
|
// check the condition
|
||||||
|
try {
|
||||||
|
if (!activity.CanExecute(workflowContext, activityContext)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Logger.Error("Error while evaluating an activity condition on {0}: {1}", name, e.ToString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ResumeWorkflow(awaitingActivityRecord, workflowContext, tokens);
|
ResumeWorkflow(awaitingActivityRecord, workflowContext, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
// start new workflows
|
// start new workflows
|
||||||
foreach (var activityRecord in startedWorkflows) {
|
foreach (var activityRecord in startedWorkflows) {
|
||||||
|
|
||||||
|
var workflowContext = new WorkflowContext {
|
||||||
|
Content = target,
|
||||||
|
Tokens = tokens,
|
||||||
|
};
|
||||||
|
|
||||||
|
var workflowRecord = new WorkflowRecord {
|
||||||
|
WorkflowDefinitionRecord = activityRecord.WorkflowDefinitionRecord,
|
||||||
|
State = "{}",
|
||||||
|
ContentItemRecord = workflowContext.Content.ContentItem.Record
|
||||||
|
};
|
||||||
|
|
||||||
|
workflowContext.Record = workflowRecord;
|
||||||
|
|
||||||
|
var activityContext = CreateActivityContext(activityRecord, tokens);
|
||||||
|
|
||||||
|
// check the condition
|
||||||
|
try {
|
||||||
|
if(!activity.CanExecute(workflowContext, activityContext)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Logger.Error("Error while evaluating an activity condition on {0}: {1}", name, e.ToString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
StartWorkflow(workflowContext, activityRecord, tokens);
|
StartWorkflow(workflowContext, activityRecord, tokens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,16 +143,7 @@ namespace Orchard.Workflows.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void StartWorkflow(WorkflowContext workflowContext, ActivityRecord activityRecord, IDictionary<string, object> tokens) {
|
private void StartWorkflow(WorkflowContext workflowContext, ActivityRecord activityRecord, IDictionary<string, object> tokens) {
|
||||||
|
|
||||||
// workflow halted, create a workflow state
|
|
||||||
var workflow = new WorkflowRecord {
|
|
||||||
WorkflowDefinitionRecord = activityRecord.WorkflowDefinitionRecord,
|
|
||||||
State = "{}",
|
|
||||||
ContentItemRecord = workflowContext.Content.ContentItem.Record
|
|
||||||
};
|
|
||||||
|
|
||||||
workflowContext.Record = workflow;
|
|
||||||
|
|
||||||
// signal every activity that the workflow is about to start
|
// signal every activity that the workflow is about to start
|
||||||
var cancellationToken = new CancellationToken();
|
var cancellationToken = new CancellationToken();
|
||||||
InvokeActivities(activity => activity.OnWorkflowStarting(workflowContext, cancellationToken));
|
InvokeActivities(activity => activity.OnWorkflowStarting(workflowContext, cancellationToken));
|
||||||
@@ -165,11 +164,12 @@ namespace Orchard.Workflows.Services {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// workflow halted, create a workflow state
|
// workflow halted, create a workflow state
|
||||||
_workflowRepository.Create(workflow);
|
_workflowRepository.Create(workflowContext.Record);
|
||||||
|
|
||||||
foreach (var blocking in blockedOn) {
|
foreach (var blocking in blockedOn) {
|
||||||
workflow.AwaitingActivities.Add(new AwaitingActivityRecord {
|
workflowContext.Record.AwaitingActivities.Add(new AwaitingActivityRecord {
|
||||||
ActivityRecord = blocking,
|
ActivityRecord = blocking,
|
||||||
|
WorkflowRecord = workflowContext.Record
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
|
@@ -2,41 +2,42 @@
|
|||||||
@using Orchard.Workflows.Models
|
@using Orchard.Workflows.Models
|
||||||
<h1>@Html.TitleForPage(T("Running workflows").ToString()) </h1>
|
<h1>@Html.TitleForPage(T("Running workflows").ToString()) </h1>
|
||||||
|
|
||||||
<fieldset>
|
@using (Html.BeginFormAntiForgeryPost()) {
|
||||||
<table class="items">
|
<fieldset>
|
||||||
<thead>
|
<table class="items">
|
||||||
<tr>
|
<thead>
|
||||||
<th scope="col" class="checkbox"> ↓</th>
|
<tr>
|
||||||
<th scope="col">@T("Worfklow Definition")</th>
|
<th scope="col" class="checkbox"> ↓</th>
|
||||||
<th scope="col">Blocking activities</th>
|
<th scope="col">@T("Worfklow Definition")</th>
|
||||||
<th scope="col" class="actions"> </th>
|
<th scope="col">Blocking activities</th>
|
||||||
</tr>
|
<th scope="col" class="actions"> </th>
|
||||||
</thead>
|
</tr>
|
||||||
@if (Model.Workflows.Count == 0) {
|
</thead>
|
||||||
@T("No workflows associated with this content item.")
|
@if (Model.Workflows.Count == 0) {
|
||||||
}
|
@T("No workflows associated with this content item.")
|
||||||
|
}
|
||||||
|
|
||||||
@foreach (WorkflowRecord workflow in Model.Workflows) {
|
@foreach (WorkflowRecord workflow in Model.Workflows) {
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@Html.ActionLink(workflow.WorkflowDefinitionRecord.Name, "Edit", new { id = workflow.WorkflowDefinitionRecord.Id })
|
@Html.ActionLink(workflow.WorkflowDefinitionRecord.Name, "Edit", new {id = workflow.WorkflowDefinitionRecord.Id})
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@foreach (AwaitingActivityRecord awaiting in workflow.AwaitingActivities) {
|
@foreach (AwaitingActivityRecord awaiting in workflow.AwaitingActivities) {
|
||||||
@awaiting.ActivityRecord.Name.CamelFriendly()
|
@awaiting.ActivityRecord.Name.CamelFriendly()
|
||||||
<br/>
|
<br/>
|
||||||
}
|
}
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@Html.ActionLink(T("Status").ToString(), "Edit", new { id = workflow.WorkflowDefinitionRecord.Id, workflowId = workflow.Id, ReturnUrl = Html.ViewContext.HttpContext.Request.RawUrl }) |
|
@Html.ActionLink(T("Status").ToString(), "Edit", new {id = workflow.WorkflowDefinitionRecord.Id, workflowId = workflow.Id, ReturnUrl = Html.ViewContext.HttpContext.Request.RawUrl}) |
|
||||||
@Html.ActionLink(T("Delete").ToString(), "DeleteWorkflow", new { id = workflow.Id }, new { itemprop = "RemoveUrl UnsafeUrl", ReturnUrl = Html.ViewContext.HttpContext.Request.RawUrl })
|
@Html.ActionLink(T("Delete").ToString(), "DeleteWorkflow", new {id = workflow.Id}, new {itemprop = "RemoveUrl UnsafeUrl", ReturnUrl = Html.ViewContext.HttpContext.Request.RawUrl})
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
}
|
Reference in New Issue
Block a user