#pragma warning disable CS1998 public async Task ReleaseContainerInstance(ContainerInstanceReference containerInstance) { _ = containerInstance ?? throw new ArgumentNullException("Container instance reference cannot be null."); var foundInstance = GetExistingInstanceByName(containerInstance.Name); foundInstance.Available = true; }
public async Task StopContainerGroupAsync(ContainerInstanceReference containerInstance, ILogger log) { _ = containerInstance ?? throw new ArgumentNullException("Container instance reference cannot be null."); var aci = await GetContainerGroupAsync(containerInstance, log); await aci.StopAsync(); }
#pragma warning disable CS1998 public async Task <ContainerInstanceReference> ReserveEmptyContainerGroupReference(string name) { var instance = new ContainerInstanceReference() { Name = name }; Instances.Add(instance); return(instance); }
public async Task StartContainerGroupAsync(ContainerInstanceReference containerInstance, ILogger log) { _ = containerInstance ?? throw new ArgumentNullException("Container instance reference cannot be null."); log.LogInformation("(Re)Starting container instance from exsiting registration..."); await _azure.ContainerGroups.StartAsync(containerInstance.ResourceGroupName, containerInstance.Name); var containerGroup = await _azure.ContainerGroups.GetByIdAsync(containerInstance.InstanceId); await RunStateVerify(containerGroup, 5000, log); containerInstance.IpAddress = containerGroup.Refresh().IPAddress; log.LogInformation("Container instance made available."); }
private async Task <ContainerInstanceReference> CreateNewContainer( ContainerInstanceReference instanceReference, string commandLine ) { var acrHost = _config["ACRHost"]; var acrImageName = _config["ACRImgName"]; var resourceGroupName = _config["ACIResourceGroup"]; _ = acrHost ?? throw new ArgumentNullException("ACR Host cannot be null"); _ = acrImageName ?? throw new ArgumentNullException("ACR Image Name cannot be null"); _ = resourceGroupName ?? throw new ArgumentNullException("Resource Group name cannot be null"); _log.LogWarning("No previous container instances available. Creating new one..."); var containerGroup = await _containerRunner.CreateContainerGroupAsync(instanceReference.Name, resourceGroupName, $"{acrHost}/{acrImageName}", commandLine, _log); return(containerGroup); }
public async Task <string> SendRequestToContainerInstance(ContainerInstanceReference containerInstance, string path, string content, ILogger log) { var url = $"http://{containerInstance.IpAddress}:{containerInstance.ExternalPort}{path}"; log.LogWarning(url); try { using (HttpClient client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var method = new HttpMethod("GET"); var request = new HttpRequestMessage(method, url); if (content != null && content != string.Empty) { method = new HttpMethod("POST"); log.LogWarning(content); request = new HttpRequestMessage(method, url) { Content = new StringContent(content, Encoding.UTF8, "application/json") }; } using (HttpResponseMessage response = client.SendAsync(request).Result) { response.EnsureSuccessStatusCode(); return(await response.Content.ReadAsStringAsync()); } } } catch (Exception ex) { throw new UnableToRecoverException(ex.Message); } }
public async Task StopContainerActivityAsync([ActivityTrigger] ContainerInstanceReference containerInstance) { await _containerRunner.StopContainerGroupAsync(containerInstance, _log); }
public async Task <bool> RunSubOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { ContainerInstanceReference instanceRef = null; var entityId = new EntityId("ContainerInstanceStatusEntity", "ContainerInstanceStatusEntity"); var entity = context.CreateEntityProxy <IContainerInstanceStatusEntity>(entityId); try { var retryOptions = new RetryOptions(TimeSpan.FromSeconds(15), 5) { BackoffCoefficient = 1.5, Handle = (ex) => ex.InnerException.Message == TriggerRetryException.DefaultMessage }; _log.LogInformation("Starting new orchestration run..."); var blobPayload = context.GetInput <EventGridEventPayload>(); var containerGroupPrefix = _configuration["ContainerGroupPrefix"] ?? "aci-container-group"; var containerGroupName = SdkContext.RandomResourceName($"{containerGroupPrefix}-", 6); var instanceCount = 0; ContainerInstanceReference instance = null; using (await context.LockAsync(entityId)) { instance = await entity.GetNextAvailableContainerGroupAsync(); if (instance == null) { instanceCount = await entity.GetContainerGroupCountAsync(); var maxInstances = int.Parse(_configuration["MaxNumberOfInstances"]); if (instanceCount >= maxInstances) { _log.LogInformation("Maximum number of parallel container instances reached. Triggering retry."); throw new TriggerRetryException(); } instance = await entity.ReserveEmptyContainerGroupReference(containerGroupName); } } bool isNew; (isNew, instanceRef) = await context.CallActivityWithRetryAsync <(bool, ContainerInstanceReference)>( "Container_Setup_Activity", retryOptions, (instance, string.Empty) ); if (isNew) { using (await context.LockAsync(entityId)) { await entity.FillEmptyContainerGroupReference(instanceRef); } } var externalEventTriggerEventName = _configuration["WorkDoneCallbackKeyword"]; var response = await context.CallActivityWithRetryAsync <string>( "Container_StartWork_Activity", retryOptions, ( context.InstanceId, externalEventTriggerEventName, blobPayload.Data.Url, instanceRef ) ); var workDoneEvent = await context.WaitForExternalEvent <ContainerResponse>(externalEventTriggerEventName); if (!workDoneEvent.Success) { throw new TriggerRetryException(); } _log.LogInformation("Work done successfully"); await context.CallActivityAsync("Container_Stop_Activity", instanceRef); await entity.ReleaseContainerInstance(instanceRef); return(true); } catch (Exception ex) { var rethrowEx = ex; if (ex is TriggerRetryException) { _log.LogWarning("Container was unable to execute tasks. Triggering retry."); throw ex; } if (instanceRef != null) { _log.LogWarning("Shutting down container instance due to unrecoverable error."); await context.CallActivityAsync("Container_Stop_Activity", instanceRef); await entity.ReleaseContainerInstance(instanceRef); } throw rethrowEx; } }
#pragma warning disable CS1998 public async Task FillEmptyContainerGroupReference(ContainerInstanceReference containerReference) { var idx = Instances.FindIndex(instance => instance.Name == containerReference.Name); Instances[idx] = containerReference; }
public async Task <IContainerGroup> GetContainerGroupAsync(ContainerInstanceReference containerInstance, ILogger log) { _ = containerInstance ?? throw new ArgumentNullException("Container instance reference cannot be null."); return(await _azure.ContainerGroups.GetByIdAsync(containerInstance.InstanceId)); }