public static async Task DeleteContainerIfExists(string containerName) { var tcs = new TaskCompletionSource <bool>(); using (await ContainerProvider.Lock.WaitAsync().ConfigureAwait(continueOnCapturedContext: false)) { if (ContainerProvider.ExecutionStates[containerName] == ContainerExecutionState.Ready) { ContainerProvider.ExecutionStates[containerName] = ContainerExecutionState.Deleted; tcs.SetResult(result: true); } else if (ContainerProvider.ExecutionStates[containerName] == ContainerExecutionState.Deleted) { return; } else { ContainerProvider.DeletionTasks[containerName] = tcs; } } await tcs.Task.ConfigureAwait(continueOnCapturedContext : false); await ContainerProvider .DeleteContainer(containerName : containerName) .ConfigureAwait(continueOnCapturedContext: false); }
public static async Task <bool> CreateContainerIfNotExists(string containerName, string functionId, int memorySize) { using (await ContainerProvider.Lock.WaitAsync().ConfigureAwait(continueOnCapturedContext: false)) { if (ContainerProvider.ExecutionStates.ContainsKey(containerName)) { return(false); } ContainerProvider.ExecutionStates[containerName] = ContainerExecutionState.Creating; } var container = await Container .Create( name : containerName, functionId : functionId, memorySize : memorySize) .ConfigureAwait(continueOnCapturedContext: false); await MemoryProvider .AdjustReservation( containerName : containerName, memorySize : memorySize) .ConfigureAwait(continueOnCapturedContext: false); ContainerProvider.Containers[containerName] = container; ContainerProvider.ExpirationTasks[containerName] = ContainerProvider.ExpireContainer(containerName: containerName); ContainerProvider.QueueWatchTasks[containerName] = ContainerProvider.WatchFunctionExistence( functionId: functionId, containerName: containerName); using (await ContainerProvider.Lock.WaitAsync().ConfigureAwait(continueOnCapturedContext: false)) { if (ContainerProvider.DeletionTasks.ContainsKey(containerName)) { ContainerProvider.DeletionTasks[containerName].SetResult(result: true); ContainerProvider.ExecutionStates[containerName] = ContainerExecutionState.Deleted; } else { ContainerProvider.ExecutionStates[containerName] = ContainerExecutionState.Ready; } } return(true); }
private static async Task WatchFunctionExistence(string functionId, string containerName) { while (true) { var exists = await FunctionsProvider .Exists(functionId : functionId) .ConfigureAwait(continueOnCapturedContext: false); if (!exists) { await ContainerProvider .DeleteContainerIfExists(containerName : containerName) .ConfigureAwait(continueOnCapturedContext: false); } await Task .Delay(delay : TimeSpan.FromSeconds(15)) .ConfigureAwait(continueOnCapturedContext: false); } }
private static async Task ExpireContainer(string containerName) { while (true) { var timeSinceLastExecution = DateTime.UtcNow - ContainerProvider.Containers[containerName].LastExecutionTime; var expirationTimeSpan = TimeSpan.FromMinutes(ServerlessConfiguration.ContainerLifeInMinutes); if (timeSinceLastExecution >= expirationTimeSpan) { var delete = false; using (await ContainerProvider.Lock.WaitAsync().ConfigureAwait(continueOnCapturedContext: false)) { if (ContainerProvider.ExecutionStates[containerName] == ContainerExecutionState.Ready) { ContainerProvider.ExecutionStates[containerName] = ContainerExecutionState.Deleted; delete = true; } else if (ContainerProvider.ExecutionStates[containerName] == ContainerExecutionState.Deleted) { return; } } if (delete) { await ContainerProvider .DeleteContainer(containerName : containerName) .ConfigureAwait(continueOnCapturedContext: false); return; } } await Task .Delay(delay : expirationTimeSpan - timeSinceLastExecution) .ConfigureAwait(continueOnCapturedContext: false); } }