Skip to content

Instantly share code, notes, and snippets.

View alistairjevans's full-sized avatar

Alistair Evans alistairjevans

View GitHub Profile
@alistairjevans
alistairjevans / single-server-lock.cs
Last active April 30, 2019 12:23
Example of a lock
lock(someSharedResource)
{
// Do some work using the resource
// and maybe update it.
}
@alistairjevans
alistairjevans / LockModel.cs
Last active April 30, 2019 16:43
MongoDB Lock - Setting Up
public class LockModel
{
// We only need an ID right now
public string Id { get; set; }
}
@alistairjevans
alistairjevans / LockProvider.cs
Last active April 30, 2019 17:04
MongoDB Lock - Lock Provider Signature
public class LockProvider
{
private readonly IMongoCollection<LockModel> collection;
public LockProvider(string mongodbConnString) {} // Collapsed
public async Task<IDisposable> AcquireLock(string resourceId)
{
// Determine the id of the lock
var lockId = $"lock_{resourceId}";
@alistairjevans
alistairjevans / DistributedLock.cs
Created April 30, 2019 17:08
MongoDB Lock - DistributedLock - Part 1
public class DistributedLock : IDisposable
{
private readonly IMongoCollection<LockModel> collection;
private readonly string lockId;
public DistributedLock(IMongoCollection<LockModel> collection, string lockId)
{
this.collection = collection;
this.lockId = lockId;
}
@alistairjevans
alistairjevans / DistributedLock.cs
Created April 30, 2019 17:35
DistributedLock with concurrency handling
try
{
var response = await collection.FindOneAndUpdateAsync<LockModel>(
// Collapsed
);
// If the result of the FindOneAndUpdateAsync is null, then that means there was no record
// before we ran our statement, so we now have the lock.
// If the result is not null, then it means a document for the lock already existed, so someone else has the lock.
if (response == null)
using (await LockProvider.AcquireLock(id))
{
// Do some work
}
@alistairjevans
alistairjevans / LockModel.cs
Last active May 1, 2019 11:17
LockModel with a TTL Index
public class LockModel
{
public string Id { get; set; }
/// <summary>
/// I'm going to set this to the moment in time when the lock should be cleared.
/// </summary>
public DateTime ExpireAt { get; set; }
}
@alistairjevans
alistairjevans / DistributedLock.cs
Last active May 1, 2019 11:29
Distributed lock with added expiry.
var response = await collection.FindOneAndUpdateAsync<LockModel>(
// Find a record with the lock ID
x => x.Id == lockId,
// If our 'upsert' creates a document, set the ID to the lock ID
Builders<LockModel>.Update
.SetOnInsert(x => x.Id, lockId)
.SetOnInsert(x => x.ExpireAt, DateTime.UtcNow.AddMinutes(1)),
new FindOneAndUpdateOptions<LockModel>
{
// If the record doesn't exist, create it.
@alistairjevans
alistairjevans / app.ino
Last active May 11, 2019 10:21
My First Arduino Program
void setup()
{
// Configure the LED pin
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
// Set the PIN to 'high'
digitalWrite(LED_BUILTIN, HIGH);
@alistairjevans
alistairjevans / app.ino
Created May 11, 2019 09:04
Anatomy of an Arduino App
void setup()
{
// Do your setup here,
// configure your board, and so on.
}
void loop()
{
// Called continuously. This is where you
// will do the bulk of your work.