public Host(IStaticApplicationInfo applicationInfo, FunctionsHostConfiguration configuration, ILogger logger, uint processId, Stopwatch stopwatch, Guid invocationId) { this.processId = processId; this.stopwatch = stopwatch; this.applicationInfo = applicationInfo; this.configuration = configuration; this.hostName = Environment.MachineName; bool cloud = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("REACTIVE_MACHINE_DIR")); CombinedLogger = new CombinedLogger(logger, configuration, processId, cloud); HostLogger = new LoggerWrapper(CombinedLogger, $"[p{processId:d3} host] ", configuration.HostLogLevel); ApplicationLogger = new LoggerWrapper(CombinedLogger, $"[p{processId:d3} application] ", configuration.ApplicationLogLevel); RuntimeLogger = new LoggerWrapper(CombinedLogger, $"[p{processId:d3} runtime] ", configuration.RuntimeLogLevel); this.application = Compilation.Compile <TStaticApplicationInfo>(applicationInfo, configuration); this.invocationId = invocationId; this.payloadSerializer = new DataContractSerializer(typeof(List <KeyValuePair <long, IMessage> >), application.SerializableTypes); this.payloadSerializerLoopback = new DataContractSerializer(typeof(List <IMessage>), application.SerializableTypes); this.Connections = new EventHubsConnections(processId, HostLogger, configuration.ehConnectionString); if (application.TryGetConfiguration <ReactiveMachine.TelemetryBlobWriter.Configuration>(out var config)) { this.collectHostEvents = config.CollectHostEvents; this.blobTelemetryListener = new TelemetryCollector(config, application, processId, this.GetType()); } }
public static ClientConnection Get(IStaticApplicationInfo applicationInfo, ILogger logger) { lock (lockable) { instance = new ClientConnection(applicationInfo, logger); } return(instance); }
private ClientConnection(IStaticApplicationInfo applicationInfo, ILogger logger) { this.applicationInfo = applicationInfo; var configuration = applicationInfo.GetHostConfiguration(); this.logger = new LoggerWrapper(logger, $"[client] ", configuration.HostLogLevel); this.application = applicationInfo.Build(new ReactiveMachine.ApplicationCompiler().SetConfiguration(configuration)); this.payloadSerializer = new DataContractSerializer(typeof(List <IMessage>), application.SerializableTypes); this.processId = (uint)new Random().Next((int)application.NumberProcesses); // we connect to a randomly selected process this.connections = new EventHubsConnections(processId, logger, configuration.ehConnectionString); this.sender = new RequestSender(processId, connections, logger, payloadSerializer, configuration); }
private Client(ILogger logger) { this.random = new Random(); this.applicationInfo = new TStaticApplicationInfo(); this.configuration = applicationInfo.GetHostConfiguration(); this.logger = new LoggerWrapper(logger, $"[client] ", configuration.HostLogLevel); this.application = Compilation.Compile <TStaticApplicationInfo>(applicationInfo, configuration); this.processId = (uint)random.Next((int)application.NumberProcesses); // we connect to a randomly selected process this.responsePartition = (uint)random.Next(ResponseSender.NumberPartitions); // we receive on a randomly selected partition this.connections = new EventHubsConnections(processId, logger, configuration.ehConnectionString); this.requestSender = new RequestSender(processId, connections, logger, new DataContractSerializer(typeof(List <IMessage>), application.SerializableTypes), configuration); this.responseSenders = new Dictionary <uint, ResponseSender>(); this.continuations = new ConcurrentDictionary <Guid, object>(); this.serializer = new Serializer(application.SerializableTypes); this.responseSerializer = new DataContractSerializer(typeof(List <IResponseMessage>), application.SerializableTypes); var ignoredTask = ListenForResponses(); }
internal static ICompiledApplication Compile <TApplicationInfo>(IStaticApplicationInfo info, FunctionsHostConfiguration configuration) where TApplicationInfo : IStaticApplicationInfo, new() { var compiler = new ReactiveMachine.ApplicationCompiler(); compiler .SetConfiguration(configuration) .AddBuildStep(serviceBuilder => { var m = typeof(Compilation).GetMethod(nameof(Compilation.DefineForResultType)); foreach (var t in info.GetResultTypes()) { var mg = m.MakeGenericMethod(typeof(TApplicationInfo), t); mg.Invoke(null, new object[] { serviceBuilder }); } }) ; return(info.Build(compiler)); }
public static async Task Doorbell(IStaticApplicationInfo applicationInfo, Microsoft.Azure.WebJobs.ExecutionContext executionContext, ILogger logger, EventData[] messages) { var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); var msg = DoorbellMessage.Deserialize(messages[0].Body.Array); var processId = msg.ProcessId; var configuration = applicationInfo.GetHostConfiguration(); var hostlogger = new LoggerWrapper(logger, $"[p{processId:d3} doorbell] "); var lastRing = messages[messages.Length - 1].SystemProperties.SequenceNumber; try { var cloudBlobContainer = await AzureBlobStorageStateManager.GetCloudBlobContainer(configuration.StorageConnectionString, hostlogger); var stateBlob = cloudBlobContainer.GetBlockBlobReference(AzureBlobStorageStateManager.BlobName(processId)); var leaseManager = new LeaseManager(stateBlob); if (await leaseManager.TryGetLease(hostlogger)) { hostlogger.LogInformation($"{DateTime.UtcNow:o} Rings x{messages.Length} on {Environment.MachineName}, through #{lastRing}, lease acquired"); await RunHost(applicationInfo, configuration, processId, hostlogger, logger, leaseManager, stopwatch, executionContext.InvocationId); } else { hostlogger.LogInformation($"{DateTime.UtcNow:o} Rings x{messages.Length} on {Environment.MachineName}, through #{lastRing}, ignored"); } } catch (Exception e) { hostlogger.LogError($"Doorbell failed: {e}"); } }
private static async Task RunHost(IStaticApplicationInfo applicationInfo, FunctionsHostConfiguration configuration, uint processId, ILogger hostlogger, ILogger logger, LeaseManager leaseManager, System.Diagnostics.Stopwatch stopwatch, Guid invocationId) { try { var host = new Host <TStaticApplicationInfo>(applicationInfo, configuration, logger, processId, stopwatch, invocationId); var done = await host.ResumeFromCheckpoint(leaseManager); // if we get here, there is no more work for this process await leaseManager.Release(); hostlogger.LogInformation($"Lease released"); if (!done) { await host.RingMyself(); } else { await host.FinalRecheck(); } await host.Cleanup(false); } catch (Exception e) { hostlogger.LogError($"RunHost Failed: {e}"); // throw exception, so event hub delivers doorbell message again // TODO think about poison messages throw; } finally { hostlogger.LogDebug($"Control returned"); } }
public static async Task <string> InitializeService(IStaticApplicationInfo applicationInfo, Microsoft.Azure.WebJobs.ExecutionContext executionContext, ILogger logger) { var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); logger = new LoggerWrapper(logger, "[initialize] "); try { var configuration = applicationInfo.GetHostConfiguration(); var host = new Host(applicationInfo, configuration, logger, 0, stopwatch, executionContext.InvocationId); var deploymentTimestamp = DateTime.UtcNow; var deploymentId = applicationInfo.GetDeploymentId(deploymentTimestamp); host.SetDeploymentTimestamp(deploymentTimestamp); // generate blobs var cloudBlobContainer = await AzureBlobStorageStateManager.GetCloudBlobContainer( storageConnectionString : configuration.StorageConnectionString, logger : logger, initialize : true ); // check the current position in all the queues, and start from there var initTasks = new List <Task>(); for (uint i = 0; i < host.NumberProcesses; i++) { StartTask(initTasks, async() => { uint processId = i; var lastEnqueued = await host.GetLastEnqueuedSequenceNumber(processId); await AzureBlobStorageStateManager.Save( cloudBlobContainer, deploymentId, logger, processId, new ProcessState(deploymentTimestamp, lastEnqueued)); }); } await Task.WhenAll(initTasks); // send ping message to process 0 var guid = Guid.NewGuid(); var message = new DoorbellMessage() { ProcessId = 0, Guid = guid }; var messageBytes = DoorbellMessage.Serialize(message); await host.Connections.GetDoorbellSender(0).SendAsync(new EventData(messageBytes)); await host.Cleanup(true); return(deploymentId); } catch (Exception e) { logger.LogError($"Initialize failed: {e}"); throw; } }
public static async Task ForkOrchestration(IOrchestration orchestration, IStaticApplicationInfo applicationInfo, ILogger logger) { var client = ClientConnection.Get(applicationInfo, logger); await client.Fork(orchestration); }