public async Task <bool> Reserve(string value, string scope, string ownerToken, TimeSpan?lease = null) { if (value == null) { throw new ArgumentNullException("value"); } if (scope == null) { throw new ArgumentNullException("scope"); } if (ownerToken == null) { throw new ArgumentNullException("ownerToken"); } var now = Clock.Now(); var expiration = now + (lease ?? TimeSpan.FromMinutes(1)); var key = Tuple.Create(value, scope); ReservedValue reservedValueInDictionary; reservedValues.TryGetValue(key, out reservedValueInDictionary); // Make sure to create a new object. Don't use the object from Dictionary directly. var reservedValue = reservedValueInDictionary == null ? null : reservedValueInDictionary.Clone(); if (reservedValue == null) { // if not, create a new ticket reservedValue = new ReservedValue { OwnerToken = ownerToken, Scope = scope, Value = value, Expiration = expiration, ConfirmationToken = value }; return(reservedValues.TryAdd(key, reservedValue)); } else if (reservedValue.Expiration == null) { return(reservedValue.OwnerToken == ownerToken); } else if (reservedValue.OwnerToken == ownerToken) { // if it's the same, extend the lease var newReservedValue = reservedValue.Clone(); newReservedValue.Expiration = expiration; return(reservedValues.TryUpdate(key, newReservedValue, reservedValue)); } else if (reservedValue.Expiration < now) { // take ownership if the reserved value has expired var newReservedValue = reservedValue.Clone(); newReservedValue.OwnerToken = ownerToken; newReservedValue.Expiration = expiration; return(reservedValues.TryUpdate(key, newReservedValue, reservedValue)); } return(false); }
public async Task<bool> Reserve(string value, string scope, string ownerToken, TimeSpan? lease = null) { if (value == null) { throw new ArgumentNullException("value"); } if (scope == null) { throw new ArgumentNullException("scope"); } if (ownerToken == null) { throw new ArgumentNullException("ownerToken"); } var now = Clock.Now(); var expiration = now + (lease ?? TimeSpan.FromMinutes(1)); var key = Tuple.Create(value, scope); ReservedValue reservedValueInDictionary; reservedValues.TryGetValue(key, out reservedValueInDictionary); // Make sure to create a new object. Don't use the object from Dictionary directly. var reservedValue = reservedValueInDictionary == null ? null : reservedValueInDictionary.Clone(); if (reservedValue == null) { // if not, create a new ticket reservedValue = new ReservedValue { OwnerToken = ownerToken, Scope = scope, Value = value, Expiration = expiration, ConfirmationToken = value }; return reservedValues.TryAdd(key, reservedValue); } else if (reservedValue.Expiration == null) { return reservedValue.OwnerToken == ownerToken; } else if (reservedValue.OwnerToken == ownerToken) { // if it's the same, extend the lease var newReservedValue = reservedValue.Clone(); newReservedValue.Expiration = expiration; return reservedValues.TryUpdate(key, newReservedValue, reservedValue); } else if (reservedValue.Expiration < now) { // take ownership if the reserved value has expired var newReservedValue = reservedValue.Clone(); newReservedValue.OwnerToken = ownerToken; newReservedValue.Expiration = expiration; return reservedValues.TryUpdate(key, newReservedValue, reservedValue); } return false; }
void Initialize() { if (initialized) { return; } initialized = true; var min = Mathf.RoundToInt(range.x); var max = Mathf.RoundToInt(range.y); var length = max - min; values = new ReservedValue[length]; for (int i = 0; i < length; i++) { values[i] = new ReservedValue(i + min); } }
public async Task<bool> Reserve(string value, string scope, string ownerToken, TimeSpan? lease = null) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (scope == null) { throw new ArgumentNullException(nameof(scope)); } if (ownerToken == null) { throw new ArgumentNullException(nameof(ownerToken)); } var now = Clock.Now(); using (var db = CreateReservationServiceDbContext()) { var reservedValues = db.Set<ReservedValue>(); var expiration = now + (lease ?? TimeSpan.FromMinutes(1)); // see if there is a pre-existing lease by the same actor var reservedValue = reservedValues.SingleOrDefault(r => r.Scope == scope && r.Value == value); if (reservedValue == null) { // if not, create a new ticket reservedValue = new ReservedValue { OwnerToken = ownerToken, Scope = scope, Value = value, Expiration = expiration, ConfirmationToken = value }; reservedValues.Add(reservedValue); } else if (reservedValue.Expiration == null) { return reservedValue.OwnerToken == ownerToken; } else if (reservedValue.OwnerToken == ownerToken) { // if it's the same, extend the lease reservedValue.Expiration = expiration; } else if (reservedValue.Expiration < now) { // take ownership if the reserved value has expired reservedValue.OwnerToken = ownerToken; reservedValue.Expiration = expiration; } else { return false; } try { await db.SaveChangesAsync(); return true; } catch (Exception exception) { if (!exception.IsConcurrencyException()) { throw; } } return false; } }