OrleansContrib / OrleansTestKit

Unit Test Toolkit for Microsoft Orleans
http://dotnet.github.io/orleans
MIT License
76 stars 42 forks source link

IRemindable grains are always activated twice by CreateGrainAsync #154

Open Drinker5 opened 5 months ago

Drinker5 commented 5 months ago

IRemindable grains are always activated twice by silo.CreateGrainAsync, this is happening because of this changes

repro:

public class RemindableGrain : Grain, IGrainWithIntegerKey, IRemindable
{
    public int Times = 0;

    public override Task OnActivateAsync(CancellationToken cancellationToken)
    {
        Times++;
        return Task.CompletedTask;
    }

    public Task ReceiveReminder(string reminderName, TickStatus status) => Task.CompletedTask;
}

public class ReproTests
{
    [Fact]
    public async Task Test()
    {
        var silo = new TestKitSilo();

        var grain = await silo.CreateGrainAsync<RemindableGrain>(1);

        Assert.Equal(1, grain.Times);
    }
}

result:

Assert.Equal() Failure
Expected: 1
Actual:   2

tested on OrleansTestKit 8.0.0/4.0.0

4.0.0-beta.3 works fine

juveilko commented 2 months ago

CreateGrainAsync(IdSpan identity, CancellationToken cancellation = default) in TestKitSilo has an if branch for the IRemindables which activates and adds to active grains, then immediately after that scope those two actions are done again.

        if (grain is IRemindable)
        {
            // Used to enable reminder context on during activate
            using var reminderContext =
                 await GetReminderActivationContext(grain, cancellation).ConfigureAwait(false);

            await grain.OnActivateAsync(cancellation).ConfigureAwait(false);
            _activatedGrains.Add(grain);
        }

        await grain.OnActivateAsync(cancellation).ConfigureAwait(false);
        _activatedGrains.Add(grain);

        return (T)grain;

I'm not github savvy nor have the time to fix this, so here's a freebie for someone with spare time.