morleyc
morleyc

Reputation: 2451

Azure Table Partition Key for task management

I am storing tasks in an Azure Table, I would always retrieve them by Id.

public sealed class ProjectTask
{
    public required string Id { get; set; }
    public string? ParentId { get; set; }
    public required string Project { get; set; }
    public required string Title { get; set; }
    public required string Description { get; set; }
}

I cannot think of any suitable partition key - I do not have multiple task types, nor this will not be a multi-tenant application.

Pointers appreciated.

public async Task<ProjectTask?> GetTaskById(string id, CancellationToken cancellationToken)
{
    try
    {
        var response = await tableClient.GetEntityAsync<TableEntity>("PartitionKey", id, cancellationToken: cancellationToken);
        return /* do something */
    }
    catch (Azure.RequestFailedException ex) when (ex.Status == 404)
    {
        logger.LogWarning($"Task with ID {id} not found.");
        return null;
    }
}

Upvotes: 0

Views: 52

Answers (1)

SiddheshDesai
SiddheshDesai

Reputation: 8195

I agree with Gaurav Mantri and Adam Vincent.

If you're unsure about a suitable partition key for your Azure Table and your tasks don't have distinct attributes for partitioning, you can opt for a generic approach. This could involve using a constant value as the partition key, evenly distributing data across partitions. While it may not optimize performance, it's effective for smaller applications or when specific partitioning criteria are lacking.

Here's the code with the solution to use a constant value as the partition key:

using Azure;
using Azure.Data.Tables;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;

public sealed class ProjectTask : ITableEntity
{
    public string Id { get; set; }
    public string? ParentId { get; set; }
    public string Project { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }

   
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }

    public ProjectTask()
    {
        
        PartitionKey = DefaultPartitionKey;
        RowKey = string.Empty;
        Timestamp = null;
        ETag = ETag.All;
    }

    
    public const string DefaultPartitionKey = "Tasks";
}

public class TaskManager
{
    private readonly TableClient _tableClient;
    private readonly ILogger<TaskManager> _logger;

    public TaskManager(string connectionString, string tableName, ILogger<TaskManager> logger)
    {
        var client = new TableServiceClient(connectionString);
        _tableClient = client.GetTableClient(tableName);
        _logger = logger;
    }

    public async Task<ProjectTask> AddTask(ProjectTask task, CancellationToken cancellationToken)
    {
        await _tableClient.AddEntityAsync(task, cancellationToken: cancellationToken);
        return task;
    }

    public async Task<ProjectTask?> GetTaskById(string id, CancellationToken cancellationToken)
    {
        try
        {
            var response = await _tableClient.GetEntityAsync<ProjectTask>(id, id, cancellationToken: cancellationToken);
            return response.Value;
        }
        catch (RequestFailedException ex) when (ex.Status == 404)
        {
            _logger.LogWarning($"Task with ID {id} not found.");
            return null;
        }
    }
}

class Program
{
    static async Task Main(string[] args)
    {
        var connectionString = "DefaultEndpointsProtocol=https;AccountName=valleystrg542;AccountKey=QfTn3Vl8NOIGEdXkF1LHbnuQjx5iMAs5+t9B/ApQZ3y7dEmricI7IJ2jEmpjI+zlC5p8wZ1wVGZ/+AStfAp/eg==;EndpointSuffix=core.windows.net";
        var tableName = "Table1";

        var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder.AddConsole();
        });
        var logger = loggerFactory.CreateLogger<TaskManager>();

        var taskManager = new TaskManager(connectionString, tableName, logger);

        
        var newTask = new ProjectTask
        {
            
            Id = Guid.NewGuid().ToString(), 
            PartitionKey = ProjectTask.DefaultPartitionKey, 
            RowKey = Guid.NewGuid().ToString(), 
            Project = "Nation1",
            Title = "titles1",
            Description = "test1"
        };

        var cancellationToken = new CancellationToken();
        var addedTask = await taskManager.AddTask(newTask, cancellationToken);

        Console.WriteLine($"Task ID: {addedTask.Id}");
    }
}

Output:-

enter image description here

enter image description here

Upvotes: 0

Related Questions