Skip to content

Commit de244ff

Browse files
author
Sophia Tevosyan
committed
initial implementation
1 parent 5a445c6 commit de244ff

10 files changed

Lines changed: 460 additions & 126 deletions

File tree

src/DurableTask.Core/Entities/EventFormat/RequestMessage.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ internal class RequestMessage : EntityMessage
122122
/// </summary>
123123
public string? ClientSpanId { get; set; }
124124

125+
/// <summary>
126+
/// The dispatch count of this request message.
127+
/// </summary>
128+
public int DispatchCount { get; set; }
129+
125130
/// <inheritdoc/>
126131
public override string GetShortDescription()
127132
{

src/DurableTask.Core/Entities/OrchestrationEntityContext.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,16 @@ public void CompleteAcquire(OperationResult result, Guid criticalSectionId)
341341
this.lockAcquisitionPending = false;
342342
}
343343

344+
/// <summary>
345+
/// Called when the entity lock acquisition fails.
346+
/// </summary>
347+
public void AbandonAcquire()
348+
{
349+
this.criticalSectionLocks = null;
350+
this.criticalSectionId = null;
351+
this.lockAcquisitionPending = false;
352+
}
353+
344354
internal void AdjustOutgoingMessage(string instanceId, RequestMessage requestMessage, DateTime? cappedTime, out string eventName)
345355
{
346356
if (cappedTime.HasValue)

src/DurableTask.Core/History/HistoryEvent.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ protected HistoryEvent(int eventId)
8989
[DataMember]
9090
public virtual EventType EventType { get; private set; }
9191

92+
/// <summary>
93+
/// Gets or sets the number of times this event has been dispatched.
94+
/// </summary>
95+
[DataMember]
96+
public int DispatchCount { get; set; }
97+
9298
/// <summary>
9399
/// Implementation for <see cref="IExtensibleDataObject.ExtensionData"/>.
94100
/// </summary>

src/DurableTask.Core/IOrchestrationService.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ public interface IOrchestrationService
102102
/// </summary>
103103
BehaviorOnContinueAsNew EventBehaviourForContinueAsNew { get; }
104104

105+
/// <summary>
106+
/// Gets the maximum amount of times the same event can be dispatched before it is considered "poisonous"
107+
/// and the corresponding operation is failed.
108+
/// </summary>
109+
int MaxDispatchCount { get; }
110+
105111
/// <summary>
106112
/// Wait for the next orchestration work item and return the orchestration work item
107113
/// </summary>

src/DurableTask.Core/Logging/EventIds.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,6 @@ static class EventIds
7171
public const int OrchestrationDebugTrace = 73;
7272

7373
public const int OrchestrationCompletedWithWarning = 74;
74+
public const int PoisonMessageDetected = 75;
7475
}
7576
}

src/DurableTask.Core/Logging/LogEvents.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,5 +1945,54 @@ void IEventSourceEvent.WriteEventSource() =>
19451945
Utils.PackageVersion);
19461946
}
19471947

1948+
/// <summary>
1949+
/// Log event representing the discarding of a "poison" message.
1950+
/// </summary>
1951+
internal class PoisonMessageDetected : StructuredLogEvent, IEventSourceEvent
1952+
{
1953+
public PoisonMessageDetected(OrchestrationInstance orchestrationInstance, string eventType, string taskEventId, string details)
1954+
{
1955+
this.InstanceId = orchestrationInstance?.InstanceId ?? string.Empty;
1956+
this.ExecutionId = orchestrationInstance?.ExecutionId ?? string.Empty;
1957+
this.EventType = eventType;
1958+
this.EventId = taskEventId;
1959+
this.Details = details;
1960+
}
1961+
1962+
[StructuredLogField]
1963+
public string InstanceId { get; }
1964+
1965+
[StructuredLogField]
1966+
public string ExecutionId { get; }
1967+
1968+
[StructuredLogField]
1969+
public string EventType { get; }
1970+
1971+
[StructuredLogField]
1972+
public string EventId { get; }
1973+
1974+
[StructuredLogField]
1975+
public string Details { get; }
1976+
1977+
public override EventId EventId => new EventId(
1978+
EventIds.PoisonMessageDetected,
1979+
nameof(EventIds.PoisonMessageDetected));
1980+
1981+
public override LogLevel Level => LogLevel.Error;
1982+
1983+
protected override string CreateLogMessage() =>
1984+
$"{this.InstanceId}: Poison message detected for {GetEventDescription(this.EventType, this.TaskEventId)}: {this.Details}";
1985+
1986+
void IEventSourceEvent.WriteEventSource() =>
1987+
StructuredEventSource.Log.DiscardingMessage(
1988+
this.InstanceId,
1989+
this.ExecutionId,
1990+
this.EventType,
1991+
this.TaskEventId,
1992+
this.Details,
1993+
Utils.AppName,
1994+
Utils.PackageVersion);
1995+
}
1996+
19481997
}
19491998
}

src/DurableTask.Core/Logging/LogHelper.cs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313
#nullable enable
1414
namespace DurableTask.Core.Logging
1515
{
16-
using System;
17-
using System.Collections.Generic;
18-
using System.Text;
1916
using DurableTask.Core.Command;
17+
using DurableTask.Core.Common;
18+
using DurableTask.Core.Entities.EventFormat;
2019
using DurableTask.Core.Entities.OperationFormat;
2120
using DurableTask.Core.History;
2221
using Microsoft.Extensions.Logging;
22+
using System;
23+
using System.Collections.Generic;
24+
using System.Text;
2325

2426
class LogHelper
2527
{
@@ -745,6 +747,42 @@ internal void RenewActivityMessageFailed(TaskActivityWorkItem workItem, Exceptio
745747
this.WriteStructuredLog(new LogEvents.RenewActivityMessageFailed(workItem, exception), exception);
746748
}
747749
}
750+
751+
/// <summary>
752+
/// Logs that a "poison message" has been detected and is being dropped.
753+
/// </summary>
754+
/// <param name="orchestrationInstance">The orchestration instance this event was sent to.</param>
755+
/// <param name="historyEvent">The "poisoned" event.</param>
756+
/// <param name="details">Extra details related to the processing of this poison message.</param>
757+
internal void PoisonMessageDetected(OrchestrationInstance? orchestrationInstance, HistoryEvent historyEvent, string details)
758+
{
759+
if (this.IsStructuredLoggingEnabled)
760+
{
761+
this.WriteStructuredLog(new LogEvents.PoisonMessageDetected(
762+
orchestrationInstance,
763+
historyEvent.EventType.ToString(),
764+
Utils.GetTaskEventId(historyEvent).ToString(),
765+
details));
766+
}
767+
}
768+
769+
/// <summary>
770+
/// Logs that a "poison" entity request message has been detected and is being dropped.
771+
/// </summary>
772+
/// <param name="orchestrationInstance">The orchestration instance this event was sent to.</param>
773+
/// <param name="requestMessage">The "poisoned" reuest message.</param>
774+
/// <param name="details">Extra details related to the processing of this poison message.</param>
775+
internal void PoisonMessageDetected(OrchestrationInstance orchestrationInstance, RequestMessage requestMessage, string details)
776+
{
777+
if (this.IsStructuredLoggingEnabled)
778+
{
779+
this.WriteStructuredLog(new LogEvents.PoisonMessageDetected(
780+
orchestrationInstance,
781+
requestMessage.IsLockRequest ? "LockRequest" : "OperationRequest",
782+
requestMessage.Id.ToString(),
783+
details));
784+
}
785+
}
748786
#endregion
749787

750788
internal void OrchestrationDebugTrace(string instanceId, string executionId, string details)

0 commit comments

Comments
 (0)