为什么演员国家失去了?

时间:2016-04-26 16:41:31

标签: azure-service-fabric

我正在Azure Service Fabric中创建一个actor服务。部署到Azure时,它似乎首先工作。可以添加和返回文本(actor由Web API提供),但在空闲一段时间后,GetTextsAsync返回一个空集合。

编辑: 我已经更新了代码以在添加之前检查状态是否存在,但它无法解决问题。

[StatePersistence(StatePersistence.Persisted)]
public class TextActor : Actor, ITextActor
{
    protected override async Task OnAactivateAsync()
    {
       if(!await StateManager.ContainsStateAsync("State"))
       {
          await this.StateManager.TryAddStateAsync<List<string>>("State", new List<string>());
       }

    }

    public async Task AddTextAsync(string text)
    {
        var texts = await this.StateManager.GetStateAsync<List<string>>("State");

        texts.Add(text);

        await this.StateManager.SetStateAsync("State", texts);
    }

    public async Task<List<string>> GetTextsAsync()
    {
        return await this.StateManager.GetStateAsync<List<string>>("State");
    }
}

EDIT2: 似乎演员本身就被取代了。我修改了actor以返回其ActorId,当文本列表消失时,ActorId也被替换为new。

我正在遵循VoiceMailBox示例中的模式,其中actor在控制器中静态创建。这是问题吗?

public class TextsController : ApiController
{
    private static Uri serviceUri = new Uri("fabric:/TextApp/TextActorService");
    private static ActorId actorId = ActorId.CreateRandom();
    private static ITextActor textActor = ActorProxy.Create<ITextActor>(actorId, serviceUri);        


    [HttpGet]
    public async Task<IHttpActionResult> GetTexts()
    {
        var texts = await textActor.GetTextsAsync();
        return Ok(texts);            
    }

    //Methods omitted
}

2 个答案:

答案 0 :(得分:3)

这是因为OnActivate()方法中的代码 - 它将状态重置为新列表。

OnActivate()方法可以在actor上多次调用 - 它不会在第一次创建特定actor时被调用。如果actor在一段时间内没有使用,那么它将被取消激活(并调用OnDeactivateAsync()方法)。但是当对演员进行新的调用时,它会再次激活。

关于演员生命周期https://azure.microsoft.com/en-gb/documentation/articles/service-fabric-reliable-actors-lifecycle/

,可能值得一读

答案 1 :(得分:1)

如何使用OnActivate()方法初始化您的状态,而不是根据需要在AddTextAsync(string text)方法中对其进行初始化?

public async Task AddTextAsync(string text)
{
    // Try and get the state
    var conditionalTexts = await this.StateManager.TryGetStateAsync<List<string>>("State");
    // If it exists, use it, otherwise create a new one
    List<string> texts = conditionalTexts.HasValue ? conditionalTexts.Value : new List<string>();
    // Make your changes
    texts.Add(text);
    // Save the state
    await this.StateManager.SetStateAsync("State", texts);
}