Skip to content

Commit

Permalink
Update ResourceId property of DistributedLease to support string IDs (#8
Browse files Browse the repository at this point in the history
)

* Updated resource id property of DistributedLease to support string values instead of only Guid

* Specify the string length for EF Core ResourceId

* Bump the package version

---------

Co-authored-by: Andrew Moreno <Andrew.Moreno@assurant.com>
Co-authored-by: f1x3d <17356460+f1x3d@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 7, 2024
1 parent 1472e1e commit 82b7410
Show file tree
Hide file tree
Showing 10 changed files with 36 additions and 23 deletions.
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
<PackageId>$(AssemblyName)</PackageId>
<PackageTags>distributed lease lock manager dlm concurrency aspnet</PackageTags>

<Version>1.1.0</Version>
<PackageValidationBaselineVersion>1.0.0</PackageValidationBaselineVersion>
<Version>2.0.0</Version>
<PackageValidationBaselineVersion>2.0.0</PackageValidationBaselineVersion>

<Authors>Oleksandr Manyk</Authors>
<PackageProjectUrl>https://github.com/f1x3d/DistributedLeaseManager</PackageProjectUrl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ await _blobServiceClient
}
}

public async Task<DistributedLease?> Find(string resourceCategory, Guid resourceId)
public async Task<DistributedLease?> Find(string resourceCategory, string resourceId)
{
using var blobStream = new MemoryStream();

Expand Down Expand Up @@ -111,6 +111,6 @@ public async Task<bool> Remove(DistributedLease lease)
private static string GetBlobPath(DistributedLease lease)
=> GetBlobPath(lease.ResourceCategory, lease.ResourceId);

private static string GetBlobPath(string resourceCategory, Guid resourceId)
private static string GetBlobPath(string resourceCategory, string resourceId)
=> $"{resourceCategory}/{resourceId}.json";
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@ await _cosmosClient
}
}

public async Task<DistributedLease?> Find(string resourceCategory, Guid resourceId)
public async Task<DistributedLease?> Find(string resourceCategory, string resourceId)
{
try
{
var response = await _cosmosClient
.GetDatabase(_options.DatabaseName)
.GetContainer(_options.ContainerName)
.ReadItemAsync<JObject>(resourceId.ToString(), new(GetPartitionKey(resourceCategory, resourceId)));
.ReadItemAsync<JObject>(resourceId, new(GetPartitionKey(resourceCategory, resourceId)));

return new()
{
ResourceId = response.Resource["id"].ToObject<Guid>(),
ResourceId = response.Resource["id"].ToObject<string>(),
ResourceCategory = response.Resource["category"].ToObject<string>(),
ExpirationTime = response.Resource["expirationTime"].ToObject<DateTimeOffset>(),
ETag = response.ETag,
Expand Down Expand Up @@ -102,25 +102,25 @@ public async Task<bool> Remove(DistributedLease lease)
await _cosmosClient
.GetDatabase(_options.DatabaseName)
.GetContainer(_options.ContainerName)
.DeleteItemAsync<JObject>(lease.ResourceId.ToString(), new(GetPartitionKey(lease)));
.DeleteItemAsync<JObject>(lease.ResourceId, new(GetPartitionKey(lease)));

return true;
}

private static string GetPartitionKey(DistributedLease lease)
=> GetPartitionKey(lease.ResourceCategory, lease.ResourceId);

private static string GetPartitionKey(string resourceCategory, Guid resourceId)
private static string GetPartitionKey(string resourceCategory, string resourceId)
=> $"{resourceCategory}/{resourceId}";

private JObject CreateLease(DistributedLease lease) =>
CreateLease(lease.ResourceId, lease.ResourceCategory, lease.ExpirationTime, GetPartitionKey(lease));

private JObject CreateLease(Guid resourceId, string category, DateTimeOffset expirationTime, string partitionKey)
private JObject CreateLease(string resourceId, string category, DateTimeOffset expirationTime, string partitionKey)
{
return new()
{
["id"] = resourceId.ToString(),
["id"] = resourceId,
["category"] = category,
["expirationTime"] = expirationTime,
[_partitionKeyPropertyName] = partitionKey,
Expand Down
2 changes: 1 addition & 1 deletion DistributedLeaseManager.Core/DistributedLease.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public class DistributedLease
{
public const string DefaultResourceCategory = "Default";

public Guid ResourceId { get; set; }
public string ResourceId { get; set; } = string.Empty;
public string ResourceCategory { get; set; } = DefaultResourceCategory;
public DateTimeOffset ExpirationTime { get; set; }
public string ETag { get; set; } = string.Empty;
Expand Down
7 changes: 3 additions & 4 deletions DistributedLeaseManager.Core/DistributedLeaseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ public DistributedLeaseManager(IDistributedLeaseRepository repository)
?? throw new ArgumentNullException(nameof(repository));
}

public Task<IDistributedLeaseAcquisitionResult> TryAcquireLease(Guid resourceId, TimeSpan duration)
public Task<IDistributedLeaseAcquisitionResult> TryAcquireLease(string resourceId, TimeSpan duration)
=> TryAcquireLease(DistributedLease.DefaultResourceCategory, resourceId, duration);

public async Task<IDistributedLeaseAcquisitionResult> TryAcquireLease(
string resourceCategory,
Guid resourceId,
public async Task<IDistributedLeaseAcquisitionResult> TryAcquireLease(string resourceCategory,
string resourceId,
TimeSpan duration)
{
await _repository.EnsureCreated();
Expand Down
4 changes: 2 additions & 2 deletions DistributedLeaseManager.Core/IDistributedLeaseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ namespace DistributedLeaseManager.Core;

public interface IDistributedLeaseManager
{
Task<IDistributedLeaseAcquisitionResult> TryAcquireLease(Guid resourceId, TimeSpan duration);
Task<IDistributedLeaseAcquisitionResult> TryAcquireLease(string resourceCategory, Guid resourceId, TimeSpan duration);
Task<IDistributedLeaseAcquisitionResult> TryAcquireLease(string resourceId, TimeSpan duration);
Task<IDistributedLeaseAcquisitionResult> TryAcquireLease(string resourceCategory, string resourceId, TimeSpan duration);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace DistributedLeaseManager.Core;
public interface IDistributedLeaseRepository
{
Task EnsureCreated();
Task<DistributedLease?> Find(string resourceCategory, Guid resourceId);
Task<DistributedLease?> Find(string resourceCategory, string resourceId);
Task<bool> Add(DistributedLease lease);
Task<bool> Update(DistributedLease lease);
Task<bool> Remove(DistributedLease lease);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public void Configure(EntityTypeBuilder<DistributedLease> builder)
.Property(x => x.ResourceCategory)
.HasMaxLength(255);

builder
.Property(x => x.ResourceId)
.HasMaxLength(255);

builder
.Property(x => x.ETag)
.HasMaxLength(36);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public async Task<bool> Add(DistributedLease lease)
}
}

public Task<DistributedLease?> Find(string resourceCategory, Guid resourceId)
public Task<DistributedLease?> Find(string resourceCategory, string resourceId)
=> _dbContext.Leases.FirstOrDefaultAsync(x =>
x.ResourceCategory == resourceCategory &&
x.ResourceId == resourceId);
Expand Down
16 changes: 13 additions & 3 deletions DistributedLeaseManager.Example/Program.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using System.Reflection;
using System.Text;
using DistributedLeaseManager.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

var builder = WebApplication.CreateBuilder(args);

// The following example uses a local Azurite instance
// See https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite
//builder.Services.AddDistributedLeaseManager("UseDevelopmentStorage=true", "distributed-leases");
//builder.Services.AddBlobStorageDistributedLeaseManager("UseDevelopmentStorage=true", "distributed-leases");

// The following example uses a local Azure Cosmos DB emulator
// See https://learn.microsoft.com/en-us/azure/cosmos-db/emulator
Expand All @@ -29,10 +31,18 @@

var app = builder.Build();

app.MapGet("/distributed-leases/{category}/{resourceId}", async ([FromServices] IDistributedLeaseManager leaseManager,
string category,
string resourceId) =>
{
var leaseResult = await leaseManager.TryAcquireLease(category, resourceId, TimeSpan.FromMinutes(1));
return JsonConvert.SerializeObject(leaseResult);
});

app.MapGet("/distributed-leases", async (IServiceProvider serviceProvider) =>
{
const int parallelGroupSize = 5;
var resourceId = Guid.NewGuid();
var resourceId = Guid.NewGuid().ToString();
var result = new StringBuilder();
var lockObject = new object();

Expand Down Expand Up @@ -63,7 +73,7 @@ await Task.WhenAll(Enumerable.Range(2, parallelGroupSize)

return result.ToString();

async Task ProcessResource(Guid resourceId, int invocationNumber, bool simulateFail = false)
async Task ProcessResource(string resourceId, int invocationNumber, bool simulateFail = false)
{
await using var scope = serviceProvider.CreateAsyncScope();
var leaseManager = scope.ServiceProvider.GetRequiredService<IDistributedLeaseManager>();
Expand Down

0 comments on commit 82b7410

Please # to comment.