Skip to content

Instantly share code, notes, and snippets.

@smaglio81
Created June 28, 2020 16:24
Show Gist options
  • Save smaglio81/eb140deb5c900a8df77d830933caff55 to your computer and use it in GitHub Desktop.
Save smaglio81/eb140deb5c900a8df77d830933caff55 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Nito.AsyncEx;
namespace YourProject
{
public interface IUpdateSequenceIdManager // you need to write your own implementation of this
{
Task<long> NextAsync();
Task<long> CurrentAsync();
}
// This uses a MSSQL database backend with a very simple table to manage sequence number generation.
// But, you need to write your own implementation of this. This one is not great.
// CREATE TABLE [dbo].[tbl_UpdateSequenceIds](
// [Name] [varchar](50) NULL,
// [Id] [bigint] NULL
// ) ON [PRIMARY]
// GO
// INSERT INTO [dbo].[tbl_UpdateSequenceIds] ([Name], [Id]) VALUES ('Current', 0)
// GO
public class UpdateSequenceIdManager : IUpdateSequenceIdManager
{
private readonly AzDPullRequestsDbContext _dbContext;
private readonly AsyncReaderWriterLock _seqLock = new AsyncReaderWriterLock();
public UpdateSequenceIdManager(YourProjectsDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<long> NextAsync()
{
using (await _seqLock.WriterLockAsync())
{
var sequenceRecord = await _dbContext.UpdateSequenceIds.FirstAsync(i => i.Name == "Current");
var next = ++sequenceRecord.Id;
await _dbContext.SaveChangesAsync();
return next;
}
}
public async Task<long> CurrentAsync()
{
using (await _seqLock.ReaderLockAsync())
{
var sequenceRecord = await _dbContext.UpdateSequenceIds.FirstAsync(i => i.Name == "Current");
return sequenceRecord.Id;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment