Fixed a bug of not properly handling DeactivateOnIdle inside ActivateAsync.

This commit is contained in:
Gabriel Kliot 2016-01-22 17:42:14 -08:00
Родитель 90beecbc95
Коммит eeb4d638bd
5 изменённых файлов: 76 добавлений и 1 удалений

Просмотреть файл

@ -175,5 +175,23 @@ namespace Orleans.Runtime
: base(info, context)
{ }
}
/// <summary>
/// Exception to indicate that the activation refused to activate by calling DeactivateOnIdle from within OnActivateAsync.
/// </summary>
[Serializable]
internal class GrainRefusedToActivateException : OrleansException
{
public GrainRefusedToActivateException() : base("Grain Refused To Activate") { }
public GrainRefusedToActivateException(string message) : base(message) { }
public GrainRefusedToActivateException(string message, Exception innerException) : base(message, innerException) { }
protected GrainRefusedToActivateException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}

Просмотреть файл

@ -111,7 +111,7 @@ namespace Orleans.Runtime
}
}
public GrainTypeManager GrainTypeManager { get; private set; }
public SiloAddress LocalSilo { get; private set; }
internal ISiloStatusOracle SiloStatusOracle { get; set; }
@ -793,6 +793,12 @@ namespace Orleans.Runtime
data.AddOnInactive(() => DestroyActivationVoid(data));
}
}
else if (data.State == ActivationState.Activating)
{
throw new GrainRefusedToActivateException(String.Format(
"Activation {0} refused to activate by calling DeactivateOnIdle from within OnActivateAsync",
data.ToString()));
}
else
{
alreadBeingDestroyed = true;

Просмотреть файл

@ -46,4 +46,10 @@ namespace UnitTests.GrainInterfaces
Task ForwardCall(IBadActivateDeactivateTestGrain otherGrain);
}
public interface IDeactivatingWhileActivatingTestGrain : IGrainWithIntegerKey
{
Task<string> DoSomething();
}
}

Просмотреть файл

@ -360,6 +360,31 @@ namespace UnitTests.Grains
}
}
internal class DeactivatingWhileActivatingTestGrain : Grain, IDeactivatingWhileActivatingTestGrain
{
private Logger logger;
public override Task OnActivateAsync()
{
logger = GetLogger();
logger.Info("OnActivateAsync");
this.DeactivateOnIdle();
return TaskDone.Done;
}
public override Task OnDeactivateAsync()
{
logger.Info("OnDeactivateAsync");
return TaskDone.Done;
}
public Task<string> DoSomething()
{
logger.Info("DoSomething");
throw new NotImplementedException("DoSomething should not have been called");
}
}
internal class CreateGrainReferenceTestGrain : Grain, ICreateGrainReferenceTestGrain
{
private Logger logger;

Просмотреть файл

@ -288,6 +288,26 @@ namespace UnitTests.ActivationsLifeCycleTests
await CheckNumActivateDeactivateCalls(1, 1, activation.ToString());
}
[TestMethod, TestCategory("Functional"), TestCategory("ActivateDeactivate")]
public async Task DeactivateOnIdleWhileActivate()
{
int id = random.Next();
IDeactivatingWhileActivatingTestGrain grain = GrainClient.GrainFactory.GetGrain<IDeactivatingWhileActivatingTestGrain>(id);
try
{
string activation = await grain.DoSomething();
Assert.Fail("Should have thrown.");
}
catch(Exception exc)
{
logger.Info("Thrown as expected:", exc);
Exception e = exc.GetBaseException();
Assert.IsTrue(e.Message.Contains("Forwarding failed"),
"Did not get expected exception message returned: " + e.Message);
}
}
private async Task CheckNumActivateDeactivateCalls(
int expectedActivateCalls,
int expectedDeactivateCalls,