예제 #1
0
        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 void Launch(ICompiledApplication application, string deploymentId)
 {
     if (application.TryGetConfiguration <Configuration>(out var config))
     {
         Launch(config, deploymentId);
     }
 }
예제 #3
0
 public SingleThreadSimulation(Configuration configuration, ICompiledApplication application, string deploymentId, DateTime deploymentTimestamp, ILogger logger)
 {
     this.configuration       = configuration;
     this.application         = application;
     this.deploymentId        = deploymentId;
     this.deploymentTimestamp = deploymentTimestamp;
     this.logger = logger;
 }
 public static T GetRequiredConfiguration <T>(this ICompiledApplication compiledApp)
 {
     if (!compiledApp.Configurations.TryGetValue(typeof(T), out var o))
     {
         throw new BuilderException($"missing configuration {typeof(T).FullName}");
     }
     return((T)o);
 }
예제 #5
0
 public MultiThreadedSimulation(Configuration configuration, ICompiledApplication application, string deploymentId, DateTime deploymentTimestamp, ILogger logger, Emulator emulator)
 {
     this.configuration       = configuration;
     this.application         = application;
     this.deploymentId        = deploymentId;
     this.deploymentTimestamp = deploymentTimestamp;
     this.logger   = logger;
     this.emulator = emulator;
 }
        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);
        }
 public static bool TryGetConfiguration <T>(this ICompiledApplication compiledApp, out T result)
 {
     if (compiledApp.Configurations.TryGetValue(typeof(T), out var o))
     {
         result = (T)o;
         return(true);
     }
     else
     {
         result = default(T);
         return(false);
     }
 }
예제 #8
0
 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.EventHubsConnectionString);
     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();
 }
예제 #9
0
        private void RunProcess(uint processId, ProcessInfo info, ICompiledApplication application)
        {
            logger.LogInformation($"Starting process {processId}.");

            info.Process.BecomePrimary();

            while (true)
            {
                List <IMessage> deliver = empty;
                lock (info)
                {
                    if (info.Inbox.Count > 0)
                    {
                        deliver        = info.Inbox;
                        info.Received += deliver.Count;
                        info.Inbox     = new List <IMessage>();
                    }
                }
                if (deliver.Count > 0)
                {
                    foreach (var m in deliver)
                    {
                        //// chaos monkey:
                        //// lose 1/2 of activity responses that originated on older instances
                        //if (configuration.DeliverStaleExternalsOneOutOf != 1
                        //    && m.MessageType == ReactiveMachine.Implementation.MessageType.RespondToActivity
                        //    && rte.InstanceId != info.Process.InstanceId
                        //    && (random.Next(configuration.DeliverStaleExternalsOneOutOf) != 0))
                        //{
                        //    continue;
                        //}

                        info.Process.ProcessMessage(m);

                        if (configuration.RoundTripProcessStateEvery < int.MaxValue &&
                            random.Next(configuration.RoundTripProcessStateEvery) == 0)        // for debugging process state serialization
                        {
                            info.Process.SaveState(out var bytes, out var label1);
                            info.Process.Restore(bytes, out var label2);
                            info.Process.BecomePrimary();
                        }
                    }
                }
            }
        }
예제 #10
0
        public void Run(ICompiledApplication application)
        {
            if (application.Configurations.TryGetValue(typeof(Configuration), out var c))
            {
                configuration = (Configuration)c;
            }
            else
            {
                configuration = new Configuration();
            }

            if (configuration.FileLogLevel != LogLevel.None)
            {
                streamWriter = new StreamWriter(Path.Combine(configuration.LocalLogDirectory, "emulatorhost.log"));
            }

            hostLogger        = new LoggerWrapper(this, "[host] ", configuration.HostLogLevel);
            applicationLogger = new LoggerWrapper(this, "[application] ", configuration.ApplicationLogLevel);
            runtimeLogger     = new LoggerWrapper(this, "[runtime] ", configuration.RuntimeLogLevel);

            application.HostServices.RegisterRuntimeLogger(runtimeLogger);
            application.HostServices.RegisterApplicationLogger(applicationLogger);

            if (!configuration.MultiThreaded)
            {
                new SingleThreadSimulation(configuration, application, deploymentId, deploymentTimestamp, hostLogger).Run(application);
            }
            else
            {
                new MultiThreadedSimulation(configuration, application, deploymentId, deploymentTimestamp, hostLogger).Run(application);
            }

            if (Debugger.IsAttached)
            {
                ReactiveMachine.TelemetryBlobWriter.TaskoMeterLauncher.Launch(application, deploymentId);
            }

            if (streamWriter != null)
            {
                var x = streamWriter;
                streamWriter = null;
                x.Close();
            }
        }
예제 #11
0
        public TelemetryCollector(Configuration configuration, ICompiledApplication application,
                                  uint processId, Type hostType)
        {
            this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
            if (string.IsNullOrEmpty(configuration.ConnectionString))
            {
                configuration.ConnectionString =
                    System.Environment.GetEnvironmentVariable("REACTIVE_MACHINE_TELEMETRY")
                    ?? "UseDevelopmentStorage=true;";
            }
            this.configurations = new Dictionary <string, object>();
            this.processId      = processId;
            this.hostType       = hostType;

            foreach (var kvp in application.Configurations)
            {
                configurations[kvp.Key.FullName] = kvp.Value;
            }

            starttime = DateTime.UtcNow;
            stopwatch.Start();
        }
 public TelemetryListenerArray(ReactiveMachine.TelemetryBlobWriter.Configuration config, ICompiledApplication application, Type hosttype, string deploymentId, DateTime deploymentTimestamp)
 {
     listeners = new TelemetryCollector[application.NumberProcesses];
     for (uint i = 0; i < application.NumberProcesses; i++)
     {
         listeners[i] = new TelemetryCollector(config, application, i, hosttype);
     }
     this.deploymentId        = deploymentId;
     this.deploymentTimestamp = deploymentTimestamp;
 }
예제 #13
0
        public void Run(ICompiledApplication application)
        {
            TelemetryListenerArray telemetry = null;

            if (application.Configurations.TryGetValue(typeof(ReactiveMachine.TelemetryBlobWriter.Configuration), out var c))
            {
                telemetry = new TelemetryListenerArray((ReactiveMachine.TelemetryBlobWriter.Configuration)c, application, this.GetType(), deploymentId, deploymentTimestamp);
                application.HostServices.RegisterTelemetryListener(telemetry);
            }

            application.HostServices.RegisterSend(Send);
            application.HostServices.RegisterGlobalExceptionHandler(HandleGlobalException);

            _serializer = new DataContractSerializer(typeof(IMessage), application.SerializableTypes);

            processes = new ProcessInfo[application.NumberProcesses];
            for (uint i = 0; i < application.NumberProcesses; i++)
            {
                processes[i] = new ProcessInfo()
                {
                    Inbox = new List <IMessage>(),
                };
            }
            for (uint i = 0; i < application.NumberProcesses; i++)
            {
                processes[i].Process = application.MakeProcess(i);
                processes[i].Process.FirstStart();
                processes[i].Process.BecomePrimary();
            }

            Console.WriteLine($"=========================== START SIMULATION ===========================");
            var stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();

            while (processes[0].Process.RequestsOutstanding())
            {
                for (uint i = 0; i < application.NumberProcesses; i++)
                {
                    var             info    = processes[i];
                    List <IMessage> deliver = empty;
                    lock (sgl)
                    {
                        if (info.Inbox.Count > 0)
                        {
                            deliver    = info.Inbox;
                            info.Inbox = new List <IMessage>();
                        }
                    }
                    if (deliver.Count > 0)
                    {
                        foreach (var m in deliver)
                        {
                            //// lose 1/2 of activity responses that originated on older instances
                            //if (configuration.DeliverStaleExternalsOneOutOf != 1
                            //    && m is ReactiveMachine.Implementation.RespondToActivity rte
                            //    && rte.InstanceId != info.Process.InstanceId
                            //    && (random.Next(configuration.DeliverStaleExternalsOneOutOf) != 0))
                            //{
                            //    continue;
                            //}

                            info.Process.ProcessMessage(m);

                            if (configuration.RoundTripProcessStateEvery < int.MaxValue &&
                                random.Next(configuration.RoundTripProcessStateEvery) == 0)    // for debugging process state serialization
                            {
                                info.Process.SaveState(out var bytes, out var label1);
                                info.Process.Restore(bytes, out var label2);
                                info.Process.BecomePrimary();
                            }
                        }
                    }
                }
            }

            Console.WriteLine($"=========================== END SIMULATION ===========================");
            stopwatch.Stop();
            Console.WriteLine($"elapsed = {stopwatch.Elapsed.TotalSeconds:f2}s  #messages={messageCount}");

            telemetry?.Shutdown().Wait();
        }
예제 #14
0
        public void Run(ICompiledApplication application)
        {
            TelemetryListenerArray telemetry = null;

            if (application.Configurations.TryGetValue(typeof(ReactiveMachine.TelemetryBlobWriter.Configuration), out var c))
            {
                telemetry = new TelemetryListenerArray((ReactiveMachine.TelemetryBlobWriter.Configuration)c, application, this.GetType(), deploymentId, deploymentTimestamp);
                application.HostServices.RegisterTelemetryListener(telemetry);
            }

            application.HostServices.RegisterSend(Send);
            application.HostServices.RegisterGlobalExceptionHandler(HandleGlobalException);
            application.HostServices.RegisterGlobalShutdown(() => shutdown.Cancel());
            _serializer = new DataContractSerializer(typeof(IMessage), application.SerializableTypes);


            processes = new ProcessInfo[application.NumberProcesses];
            for (uint i = 0; i < application.NumberProcesses; i++)
            {
                processes[i] = new ProcessInfo()
                {
                    Inbox = new List <IMessage>(),
                };
            }
            for (uint i = 0; i < application.NumberProcesses; i++)
            {
                var info = processes[i];

                logger.LogDebug($"Recovering process {i}.");

                info.Process = application.MakeProcess(i);
                info.Process.FirstStart();
            }
            for (uint i = 0; i < application.NumberProcesses; i++)
            {
                uint processId = i;
                new Thread(() => RunProcess(processId, processes[processId], application)).Start();
            }

            bool someoneBusy = true;

            while (!shutdown.IsCancellationRequested)
            {
                someoneBusy = false;
                for (uint i = 0; i < application.NumberProcesses; i++)
                {
                    var  info = processes[i];
                    long received;
                    bool busy;
                    lock (info)
                    {
                        received = info.Received;
                        busy     = (info.Inbox.Count > 0) || (info.Process?.RequestsOutstanding() ?? true);
                    }
                    someoneBusy = busy || someoneBusy;
                    logger.LogInformation($"Process {i}: Received={received:D12} busy={busy}");
                }
                if (!someoneBusy)
                {
                    break;
                }

                emulator.FlushLog();

                shutdown.Token.WaitHandle.WaitOne(TimeSpan.FromSeconds(10));
            }

            telemetry?.Shutdown().Wait();
        }