public async Task AddDeploymentUpdate(Application application, Image image, string newTag) { var currentTags = _applicationService.GetCurrentImageTags(application); if (!currentTags.TryGetValue(image, out var currentTag)) { currentTag = "<new image>"; } var deploymentUpdate = new DeploymentUpdate(application, image, currentTag, newTag); if (!_deploymentUpdates.TryAdd(deploymentUpdate, DeploymentUpdateStatus.Pending)) { _log.LogInformation( "Image tag update operation already in queue for '{Repository}' with {Tag} for application {Application} with new tag {NewTag}", image.Repository, currentTags[image], application.Name, newTag ); return; } _log.LogInformation( "Adding image tag update operation for '{Repository}' with {Tag} for application {Application} with new tag {NewTag}", image.Repository, currentTags[image], application.Name, newTag ); var queue = _pendingDeploymentUpdates.GetOrAdd(application, key => new ConcurrentQueue <DeploymentUpdate>()); queue.Enqueue(deploymentUpdate); var channel = application.Notifications.Channels.FirstOrDefault(); if (channel != null) { _log.LogInformation( "Sending notification about image tag update operation for '{Repository}' with {Tag} for application {Application} with new tag {NewTag}", image.Repository, currentTags[image], application.Name, newTag ); try { var handle = await _slackClient.SendDeploymentUpdateNotification(channel, deploymentUpdate, DeploymentUpdateStatus.Pending); _notificationHandles.TryAdd(deploymentUpdate, handle); } catch (Exception e) { _log.LogError(e, "Failed to send deployment update notification to slack"); } } }