public async Task Delete(ScaleUpRequestEntity entry) { if (entry == null) { _logger.LogWarning("ScaleUpStore was asked to delete a null entry, returning"); return; } try { _logger.LogDebug("Deleting entry '{0}:{1}' from storage", entry.EnvironmentName, entry.PoolName); var operation = TableOperation.Delete(entry); await _table.ExecuteAsync(operation); _logger.LogDebug("Entry '{0}:{1}' deleted", entry.EnvironmentName, entry.PoolName); } catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == 404) { // whole table is gone } catch (Exception ex) { // TODO: correctly handle this. This may fail due to eTag. // if so read it again and delete. _logger.LogError(ex, "Failed to delete storage entry"); } }
public async Task Add(string envName, string poolName, int requested) { async Task AddRequest() { var scaleUpEntry = await Get(envName, poolName, CancellationToken.None); if (scaleUpEntry == null) { // no entry exists so add it scaleUpEntry = new ScaleUpRequestEntity(envName, poolName) { TargetNodes = requested, }; await InsertOrMergeEntry(scaleUpEntry); } else { bool changed = false; if (requested > scaleUpEntry.TargetNodes) { changed = true; scaleUpEntry.TargetNodes = requested; } // if limits were lower then the request is ignored if (changed) { await InsertOrMergeEntry(scaleUpEntry); } } } // we will attempt up to 5 times // this should be plenty as there is a large delay on the processor side StorageException lastEx = null; for (int i = 0; i < 5; ++i) { try { await AddRequest(); return; } catch (StorageException ex) when(ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed) { // etag mismatch, try again lastEx = ex; } } // give up: _logger.LogError(lastEx, "Unable to insert scale request"); throw lastEx; }
private async Task InsertOrMergeEntry(ScaleUpRequestEntity entry) { // TODO: catch and retry if it fails as another request could have already added one // for the same environment and pool await _table.CreateIfNotExistsAsync(); var operation = TableOperation.InsertOrMerge(entry); await _table.ExecuteAsync(operation); }