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);
        }