Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always reset RuntimeContext to previous value after use #8864

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions src/Orleans.Core.Abstractions/Runtime/RuntimeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,22 @@ internal static class RuntimeContext
/// Sets the current grain context.
/// </summary>
/// <param name="newContext">The new context.</param>
/// <param name="currentContext">The current context at the time of the call.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void SetExecutionContext(IGrainContext newContext)
internal static void SetExecutionContext(IGrainContext newContext, out IGrainContext currentContext)
{
currentContext = _threadLocalContext;
_threadLocalContext = newContext;
}

/// <summary>
/// Sets the current grain context.
/// </summary>
/// <param name="newContext">The new context.</param>
/// <param name="existingContext">The existing context.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void SetExecutionContext(IGrainContext newContext, out IGrainContext existingContext)
{
existingContext = _threadLocalContext;
_threadLocalContext = newContext;
}

/// <summary>
/// Resets the current grain context.
/// Resets the current grain context to the provided original context.
/// </summary>
/// <param name="originalContext">The original context.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void ResetExecutionContext()
internal static void ResetExecutionContext(IGrainContext originalContext)
{
_threadLocalContext = null;
_threadLocalContext = originalContext;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public IGrainContext CreateContext(GrainAddress activationAddress)
_serviceProvider,
_sharedComponents);

RuntimeContext.SetExecutionContext(context, out var existingContext);
RuntimeContext.SetExecutionContext(context, out var originalContext);

try
{
Expand All @@ -126,7 +126,7 @@ public IGrainContext CreateContext(GrainAddress activationAddress)
}
finally
{
RuntimeContext.SetExecutionContext(existingContext);
RuntimeContext.ResetExecutionContext(originalContext);
}

return context;
Expand Down
2 changes: 1 addition & 1 deletion src/Orleans.Runtime/Core/SystemTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ public void ReceiveMessage(object message)
{
this.MessagingTrace.OnEnqueueMessageOnActivation(msg, this);
var workItem = new RequestWorkItem(this, msg);
this.WorkItemGroup.TaskScheduler.QueueWorkItem(workItem);
this.WorkItemGroup.TaskScheduler.QueueRequestWorkItem(workItem);
break;
}

Expand Down
1 change: 0 additions & 1 deletion src/Orleans.Runtime/Scheduler/ActivationTaskScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ internal ActivationTaskScheduler(WorkItemGroup workGroup, ILogger<ActivationTask

public void RunTask(Task task)
{
RuntimeContext.SetExecutionContext(workerGroup.GrainContext);
bool done = TryExecuteTask(task);
if (!done)
logger.LogWarning(
Expand Down
8 changes: 4 additions & 4 deletions src/Orleans.Runtime/Scheduler/ClosureWorkItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public AsyncClosureWorkItem(Func<Task> closure, IGrainContext grainContext)

public override async void Execute()
{
RuntimeContext.SetExecutionContext(GrainContext, out var originalContext);
try
{
RuntimeContext.SetExecutionContext(this.GrainContext);
RequestContext.Clear();
await this.continuation();
this.completion.TrySetResult(true);
Expand All @@ -40,7 +40,7 @@ public override async void Execute()
}
finally
{
RuntimeContext.ResetExecutionContext();
RuntimeContext.ResetExecutionContext(originalContext);
}
}

Expand Down Expand Up @@ -73,9 +73,9 @@ public AsyncClosureWorkItem(Func<Task<T>> closure, IGrainContext grainContext)

public override async void Execute()
{
RuntimeContext.SetExecutionContext(GrainContext, out var originalContext);
try
{
RuntimeContext.SetExecutionContext(this.GrainContext);
RequestContext.Clear();
var result = await this.continuation();
this.completion.TrySetResult(result);
Expand All @@ -86,7 +86,7 @@ public override async void Execute()
}
finally
{
RuntimeContext.ResetExecutionContext();
RuntimeContext.ResetExecutionContext(originalContext);
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/Orleans.Runtime/Scheduler/RequestWorkItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@ namespace Orleans.Runtime.Scheduler
internal sealed class RequestWorkItem : WorkItemBase
{
private readonly Message request;
private readonly SystemTarget target;
private readonly SystemTarget _target;

public RequestWorkItem(SystemTarget t, Message m)
{
target = t;
_target = t;
request = m;
}

public override string Name => $"RequestWorkItem:Id={request.Id}";

public override IGrainContext GrainContext => this.target;
public override IGrainContext GrainContext => _target;

public override void Execute()
{
RuntimeContext.SetExecutionContext(_target, out var originalContext);
try
{
RuntimeContext.SetExecutionContext(this.target);
target.HandleNewRequest(request);
_target.HandleNewRequest(request);
}
finally
{
RuntimeContext.ResetExecutionContext();
RuntimeContext.ResetExecutionContext(originalContext);
}
}

Expand Down
21 changes: 11 additions & 10 deletions src/Orleans.Runtime/Scheduler/TaskSchedulerUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,53 @@ namespace Orleans.Runtime.Scheduler
{
internal static class TaskSchedulerUtils
{
private static readonly Action<object> TaskFunc = (state) => RunWorkItemTask((IWorkItem)state);
private static readonly Action<object> TaskFunc = RunWorkItemTask;
private static readonly Action<object> ThreadPoolWorkItemTaskFunc = (state) => RunThreadPoolWorkItemTask((IThreadPoolWorkItem)state);

private static void RunThreadPoolWorkItemTask(IThreadPoolWorkItem todo)
{
todo.Execute();
}

private static void RunWorkItemTask(IWorkItem todo)
private static void RunWorkItemTask(object state)
{
var workItem = (RequestWorkItem)state;
RuntimeContext.SetExecutionContext(workItem.GrainContext, out var originalContext);
try
{
RuntimeContext.SetExecutionContext(todo.GrainContext);
todo.Execute();
workItem.Execute();
}
finally
{
RuntimeContext.ResetExecutionContext();
RuntimeContext.ResetExecutionContext(originalContext);
}
}

public static void QueueAction(this TaskScheduler taskScheduler, Action action)
public static void QueueAction(this ActivationTaskScheduler taskScheduler, Action action)
{
using var suppressExecutionContext = new ExecutionContextSuppressor();

var task = new Task(action);
task.Start(taskScheduler);
}

public static void QueueAction(this TaskScheduler taskScheduler, Action<object> action, object state)
public static void QueueAction(this ActivationTaskScheduler taskScheduler, Action<object> action, object state)
{
using var suppressExecutionContext = new ExecutionContextSuppressor();

var task = new Task(action, state);
task.Start(taskScheduler);
}

public static void QueueWorkItem(this TaskScheduler taskScheduler, IWorkItem todo)
public static void QueueRequestWorkItem(this ActivationTaskScheduler taskScheduler, RequestWorkItem requestWorkItem)
{
using var suppressExecutionContext = new ExecutionContextSuppressor();

var workItemTask = new Task(TaskFunc, todo);
var workItemTask = new Task(TaskFunc, requestWorkItem);
workItemTask.Start(taskScheduler);
}

public static void QueueThreadPoolWorkItem(this TaskScheduler taskScheduler, IThreadPoolWorkItem workItem)
public static void QueueThreadPoolWorkItem(this ActivationTaskScheduler taskScheduler, IThreadPoolWorkItem workItem)
{
using var suppressExecutionContext = new ExecutionContextSuppressor();

Expand Down
6 changes: 3 additions & 3 deletions src/Orleans.Runtime/Scheduler/WorkItemGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,12 @@ private static object DumpAsyncState(object o)

// Execute one or more turns for this activation.
// This method is always called in a single-threaded environment -- that is, no more than one
// thread will be in this method at once -- but other asynch threads may still be queueing tasks, etc.
// thread will be in this method at once -- but other async threads may still be queueing tasks, etc.
public void Execute()
{
RuntimeContext.SetExecutionContext(GrainContext, out var originalContext);
try
{
RuntimeContext.SetExecutionContext(this.GrainContext);

// Process multiple items -- drain the applicationMessageQueue (up to max items) for this physical activation
int count = 0;
Expand Down Expand Up @@ -264,7 +264,7 @@ public void Execute()
}
}

RuntimeContext.ResetExecutionContext();
RuntimeContext.ResetExecutionContext(originalContext);
}
}

Expand Down
Loading