Loading and using data when a stateful service starts in Azure Service Fabric

155 Views Asked by At

I am creating a Azure Service Fabric app with 3 services, two stateless services (stateless1 and stateless2) and a stateful (stateful) service.

stateful service runs with 3 partitions.

Stateful service should load data at the time of starting by calling stateless1 depending on the partition number. when stateless2 calls stateful, it should get the data from the IReliableDictionary of that partition and to return it.

All the examples are showing how to GetorAddAsync IReliableDictionary within the stateful controller.

I tried the following:

  • I try to initialize the IReliableDictionary in stateful.cs. I am getting a null pointer exception.
  • I tried it in stateful's startup.cs. I am getting the error that StateManger is not readble.
  • I also overried RunAsync and Initialized the dictionary. THe dictionary is loading correctly. But when I get the dictionary within the controller it is empty.

The code in stateful.cs is

protected override async Task RunAsync(CancellationToken cancellationToken)
{

    var wsDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, string>>("mydictionary");

    Uri serviceName = new Uri($"{Context.CodePackageActivationContext.ApplicationName}/Stateless1");
    Uri proxyAddress = this.GetProxyAddress(serviceName);
    string PartitionName = await GetPartitionName();
    string proxyUrl = $"{proxyAddress}/api/PartitionInfo/Partition/{PartitionName}/GetEntries";
    StringContent content = new StringContent($"{{'name' : '{PartitionName}'}}", Encoding.UTF8, "application/json");
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    using (HttpResponseMessage response = await httpClient.GetAsync(proxyUrl))
    {
        List<string> entries= await response.Content.ReadAsAsync<List<string>>();
        CancellationToken ct = new CancellationToken();
        using (ITransaction tx = this.StateManager.CreateTransaction())
        {
            foreach (string entry in entries)
            {
                await wsDictionary.AddOrUpdateAsync(tx, entry, entry,(key, value) => value);
                var result = await wsDictionary.TryGetValueAsync(tx, entry);
                ServiceEventSource.Current.ServiceMessage(this.Context, "ENtry for Partition {0} is {1}", PartitionName, result.HasValue ? result.Value.ToString() : "No Entry found");
            }
        }
    }
}

The code in the controller is

CancellationToken ct = new CancellationToken();
IReliableDictionary<string, string> wsDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, string>>("mydictionary");
using (ITransaction tx = this.StateManager.CreateTransaction())
{
    
    if (await wsDictionary.ContainsKeyAsync(tx, name))
    {
        List<KeyValuePair<string, string>> kvpList = new List<KeyValuePair<string, string>>()
        {
            new KeyValuePair<string, string>(name, "name exists")
        };
        return this.Json(kvpList);
    }
    else
    {
        return null;
    }
}

What is the mistake and how to correct it?

0

There are 0 best solutions below