Skip to content

Commit

Permalink
Moving RuntimeContext check inside ReminderRegistry (#8436)
Browse files Browse the repository at this point in the history
* Moving RuntimeContext check inside ReminderRegistry

* reducing test flakiness
  • Loading branch information
cmeyertons authored May 18, 2023
1 parent 4e521de commit 7243af9
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 26 deletions.
9 changes: 1 addition & 8 deletions src/Orleans.Reminders/GrainReminderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,10 @@ private static Task<List<IGrainReminder>> GetReminders(IGrainContext? grainConte
}

/// <summary>
/// Gets the <see cref="IReminderService"/>.
/// Gets the <see cref="IReminderRegistry"/>.
/// </summary>
private static IReminderRegistry GetReminderRegistry(IGrainContext grainContext)
{
if (RuntimeContext.Current is null) ThrowInvalidContext();
return grainContext.ActivationServices.GetRequiredService<IReminderRegistry>();
}

private static void ThrowInvalidContext()
{
throw new InvalidOperationException("Attempted to access grain from a non-grain context, such as a background thread, which is invalid."
+ " Ensure that you are only accessing grain functionality from within the context of a grain.");
}
}
17 changes: 12 additions & 5 deletions src/Orleans.Reminders/ReminderService/ReminderRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ public Task<IGrainReminder> RegisterOrUpdateReminder(GrainId callingGrainId, str
if (string.IsNullOrEmpty(reminderName))
throw new ArgumentException("Cannot use null or empty name for the reminder", nameof(reminderName));

EnsureReminderServiceRegistered();
EnsureReminderServiceRegisteredAndInGrainContext();
return GetGrainService(callingGrainId).RegisterOrUpdateReminder(callingGrainId, reminderName, dueTime, period);
}

public Task UnregisterReminder(GrainId callingGrainId, IGrainReminder reminder)
{
EnsureReminderServiceRegistered();
EnsureReminderServiceRegisteredAndInGrainContext();
return GetGrainService(callingGrainId).UnregisterReminder(reminder);
}

Expand All @@ -59,18 +59,19 @@ public Task<IGrainReminder> GetReminder(GrainId callingGrainId, string reminderN
if (string.IsNullOrEmpty(reminderName))
throw new ArgumentException("Cannot use null or empty name for the reminder", nameof(reminderName));

EnsureReminderServiceRegistered();
EnsureReminderServiceRegisteredAndInGrainContext();
return GetGrainService(callingGrainId).GetReminder(callingGrainId, reminderName);
}

public Task<List<IGrainReminder>> GetReminders(GrainId callingGrainId)
{
EnsureReminderServiceRegistered();
EnsureReminderServiceRegisteredAndInGrainContext();
return GetGrainService(callingGrainId).GetReminders(callingGrainId);
}

private void EnsureReminderServiceRegistered()
private void EnsureReminderServiceRegisteredAndInGrainContext()
{
if (RuntimeContext.Current is null) ThrowInvalidContext();
if (serviceProvider != null) ValidateServiceProvider();
}

Expand All @@ -89,5 +90,11 @@ private void ValidateServiceProvider()

serviceProvider = null;
}

private static void ThrowInvalidContext()
{
throw new InvalidOperationException("Attempted to access grain from a non-grain context, such as a background thread, which is invalid."
+ " Ensure that you are only accessing grain functionality from within the context of a grain.");
}
}
}
20 changes: 7 additions & 13 deletions test/TesterInternal/TimerTests/ReminderTests_Base.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
//#define USE_SQL_SERVER

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Internal;
using Orleans.Runtime;
using Orleans.TestingHost;
using Orleans.TestingHost.Utils;
using Orleans.Internal;
using TestExtensions;
using UnitTests.GrainInterfaces;
using Xunit;
Expand Down Expand Up @@ -126,11 +120,11 @@ public async Task Test_Reminders_Basic_ListOps()
// do some time tests as well
log.LogInformation("Time tests");
TimeSpan period = await grain.GetReminderPeriod(DR);
await Task.Delay(period.Multiply(2) + LEEWAY); // giving some leeway
await Task.Delay((period + LEEWAY).Multiply(2)); // giving some leeway, including leeway in each period to minimize flakiness
for (int i = 0; i < count; i++)
{
long curr = await grain.GetCounter(DR + "_" + i);
Assert.Equal(2, curr);
Assert.Equal(2, curr);
}
}

Expand All @@ -144,7 +138,7 @@ public async Task Test_Reminders_1J_MultiGrainMultiReminders()

TimeSpan period = await g1.GetReminderPeriod(DR);

Task<bool>[] tasks =
Task<bool>[] tasks =
{
Task.Run(() => this.PerGrainMultiReminderTestChurn(g1)),
Task.Run(() => this.PerGrainMultiReminderTestChurn(g2)),
Expand All @@ -169,7 +163,7 @@ public async Task Test_Reminders_ReminderNotFound()

// request a reminder that does not exist
IGrainReminder reminder = await g1.GetReminderObject("blarg");
Assert.Null(reminder);
Assert.Null(reminder);
}

internal async Task<bool> PerGrainMultiReminderTestChurn(IReminderTestGrain2 g)
Expand Down Expand Up @@ -335,12 +329,12 @@ protected async Task<bool> PerCopyGrainFailureTest(IReminderTestCopyGrain grain)
await grain.StartReminder(DR);
await Task.Delay(period.Multiply(failCheckAfter) + LEEWAY); // giving some leeway
long last = await grain.GetCounter(DR);
Assert.Equal(failCheckAfter, last); // "{0} CopyGrain {1} Reminder {2}" // Time(), grain.GetPrimaryKey(), DR);
Assert.Equal(failCheckAfter, last); // "{0} CopyGrain {1} Reminder {2}" // Time(), grain.GetPrimaryKey(), DR);

await grain.StopReminder(DR);
await Task.Delay(period.Multiply(2) + LEEWAY); // giving some leeway
long curr = await grain.GetCounter(DR);
Assert.Equal(last, curr); // "{0} CopyGrain {1} Reminder {2}", Time(), grain.GetPrimaryKey(), DR);
Assert.Equal(last, curr); // "{0} CopyGrain {1} Reminder {2}", Time(), grain.GetPrimaryKey(), DR);

return true;
}
Expand Down

0 comments on commit 7243af9

Please sign in to comment.