public static void HostStarted(ScriptHost scriptHost)
        {
            if (scriptHost == null || scriptHost.Functions == null)
            {
                return;
            }

            foreach (var function in scriptHost.Functions)
            {
                if (function == null || function.Metadata == null)
                {
                    continue;
                }

                MetricEventSource.Log.RaiseFunctionsInfoEvent(
                    siteName,
                    GetNormalizedString(function.Name),
                    function.Metadata != null
                        ? SerializeBindings(function.Metadata.InputBindings)
                        : GetNormalizedString(null),
                    function.Metadata != null
                        ? SerializeBindings(function.Metadata.OutputBindings) 
                        : GetNormalizedString(null),
                    function.Metadata.ScriptType.ToString(),
                    function.Metadata != null ? function.Metadata.IsDisabled : false);
            }
        }
        public static ScriptHost Create(ScriptHostConfiguration scriptConfig = null)
        {
            if (scriptConfig == null)
            {
                scriptConfig = new ScriptHostConfiguration()
                {
                    RootPath = Environment.CurrentDirectory
                };
            }

            if (!Path.IsPathRooted(scriptConfig.RootPath))
            {
                scriptConfig.RootPath = Path.Combine(Environment.CurrentDirectory, scriptConfig.RootPath);
            }

            JobHostConfiguration config = new JobHostConfiguration();
            ScriptHost scriptHost = new ScriptHost(config, scriptConfig);
            scriptHost.Initialize();

            return scriptHost;
        }
        public void RunAndBlock(CancellationToken cancellationToken = default(CancellationToken))
        {
            // Start the host and restart it if requested. Host Restarts will happen when
            // host level configuration files change
            do
            {
                IsRunning = false;

                _config.HostConfig = new JobHostConfiguration();
                ScriptHost newInstance = ScriptHost.Create(_config);

                newInstance.Start();
                lock (_liveInstances)
                {
                    _liveInstances.Add(newInstance);
                }
                _currentInstance = newInstance;
                OnHostStarted();

                // only after ALL initialization is complete do we set this flag
                IsRunning = true;

                // Wait for a restart signal. This event will automatically reset.
                // While we're restarting, it is possible for another restart to be
                // signaled. That is fine - the restart will be processed immediately
                // once we get to this line again. The important thing is that these
                // restarts are only happening on a single thread.
                WaitHandle.WaitAny(new WaitHandle[] {
                    newInstance.RestartEvent,
                    _stopEvent
                });

                // Orphan the current host instance. We're stopping it, so it won't listen for any new functions
                // it will finish any currently executing functions and then clean itself up.
                // Spin around and create a new host instance.
                Task tIgnore = Orphan(newInstance);
            }
            while (!_stopped);
        }
        public static ScriptHost Create(ScriptHostConfiguration scriptConfig = null)
        {
            if (scriptConfig == null)
            {
                scriptConfig = new ScriptHostConfiguration();
            }

            if (!Path.IsPathRooted(scriptConfig.RootScriptPath))
            {
                scriptConfig.RootScriptPath = Path.Combine(Environment.CurrentDirectory, scriptConfig.RootScriptPath);
            }

            ScriptHost scriptHost = new ScriptHost(scriptConfig);
            try
            {
                scriptHost.Initialize();
            }
            catch (Exception ex)
            {
                if (scriptHost.TraceWriter != null)
                {
                    scriptHost.TraceWriter.Error("ScriptHost initialization failed", ex);
                }
                throw;
            }

            return scriptHost;
        }
        public void RunAndBlock(CancellationToken cancellationToken = default(CancellationToken))
        {
            // Start the host and restart it if requested. Host Restarts will happen when
            // host level configuration files change
            do
            {
                ScriptHost newInstance = null;
                try
                {
                    // if we were in an error state retain that,
                    // otherwise move to default
                    if (State != ScriptHostState.Error)
                    {
                        State = ScriptHostState.Default;
                    }

                    // Create a new host config, but keep the host id from existing one
                    _config.HostConfig = new JobHostConfiguration
                    {
                        HostId = _config.HostConfig.HostId
                    };
                    OnInitializeConfig(_config);
                    newInstance = _scriptHostFactory.Create(_settingsManager, _config);
                    _traceWriter = newInstance.TraceWriter;

                    _currentInstance = newInstance;
                    lock (_liveInstances)
                    {
                        _liveInstances.Add(newInstance);
                    }

                    OnHostCreated();

                    if (_traceWriter != null)
                    {
                        string message = string.Format("Starting Host (HostId={0}, Version={1}, ProcessId={2}, Debug={3})",
                            newInstance.ScriptConfig.HostConfig.HostId, ScriptHost.Version, Process.GetCurrentProcess().Id, newInstance.InDebugMode.ToString());
                        _traceWriter.Info(message);
                    }
                    newInstance.StartAsync(cancellationToken).GetAwaiter().GetResult();

                    // log any function initialization errors
                    LogErrors(newInstance);

                    OnHostStarted();

                    // only after ALL initialization is complete do we set the
                    // state to Running
                    State = ScriptHostState.Running;
                    LastError = null;

                    // Wait for a restart signal. This event will automatically reset.
                    // While we're restarting, it is possible for another restart to be
                    // signaled. That is fine - the restart will be processed immediately
                    // once we get to this line again. The important thing is that these
                    // restarts are only happening on a single thread.
                    WaitHandle.WaitAny(new WaitHandle[]
                    {
                        cancellationToken.WaitHandle,
                        newInstance.RestartEvent,
                        _stopEvent
                    });

                    // Orphan the current host instance. We're stopping it, so it won't listen for any new functions
                    // it will finish any currently executing functions and then clean itself up.
                    // Spin around and create a new host instance.
                    Task taskIgnore = Orphan(newInstance);
                }
                catch (Exception ex)
                {
                    State = ScriptHostState.Error;
                    LastError = ex;

                    // We need to keep the host running, so we catch and log any errors
                    // then restart the host
                    if (_traceWriter != null)
                    {
                        _traceWriter.Error("A ScriptHost error has occurred", ex);
                    }

                    // If a ScriptHost instance was created before the exception was thrown
                    // Orphan and cleanup that instance.
                    if (newInstance != null)
                    {
                        Orphan(newInstance, forceStop: true)
                            .ContinueWith(t =>
                            {
                                if (t.IsFaulted)
                                {
                                    t.Exception.Handle(e => true);
                                }
                            }, TaskContinuationOptions.ExecuteSynchronously);
                    }

                    // Wait for a short period of time before restarting to
                    // avoid cases where a host level config error might cause
                    // a rapid restart cycle
                    Task.Delay(_config.RestartInterval).GetAwaiter().GetResult();
                }
            }
            while (!_stopped && !cancellationToken.IsCancellationRequested);
        }
 private static async Task StopAndDisposeAsync(ScriptHost instance)
 {
     try
     {
         await instance.StopAsync();
     }
     catch
     {
         // best effort
     }
     finally
     {
         instance.Dispose();
     }
 }
        /// <summary>
        /// Remove the <see cref="ScriptHost"/> instance from the live instances collection,
        /// allowing it to finish currently executing functions before stopping and disposing of it.
        /// </summary>
        /// <param name="instance">The <see cref="ScriptHost"/> instance to remove</param>
        /// <param name="forceStop">Forces the call to stop and dispose of the instance, even if it isn't present in the live instances collection.</param>
        /// <returns></returns>
        private async Task Orphan(ScriptHost instance, bool forceStop = false)
        {
            lock (_liveInstances)
            {
                bool removed = _liveInstances.Remove(instance);
                if (!forceStop && !removed)
                {
                    return; // somebody else is handling it
                }
            }

            try
            {
                // this thread now owns the instance
                if (instance.TraceWriter != null)
                {
                    instance.TraceWriter.Info("Stopping Host");
                }
                await instance.StopAsync();
            }
            finally
            {
                instance.Dispose();
            }
        }
 private static void LogErrors(ScriptHost host)
 {
     if (host.FunctionErrors.Count > 0)
     {
         StringBuilder builder = new StringBuilder();
         builder.AppendLine(string.Format(CultureInfo.InvariantCulture, "The following {0} functions are in error:", host.FunctionErrors.Count));
         foreach (var error in host.FunctionErrors)
         {
             string functionErrors = string.Join(Environment.NewLine, error.Value);
             builder.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0}: {1}", error.Key, functionErrors));
         }
         host.TraceWriter.Error(builder.ToString());
     }
 }
        // Let the existing host instance finish currently executing functions.
        private async Task Orphan(ScriptHost instance)
        {
            lock (_liveInstances)
            {
                bool removed = _liveInstances.Remove(instance);
                if (!removed)
                {
                    return; // somebody else is handling it
                }
            }

            // this thread now owns the instance
            await instance.StopAsync();
            instance.Dispose();
        }
        public void RunAndBlock(CancellationToken cancellationToken = default(CancellationToken))
        {
            // Start the host and restart it if requested. Host Restarts will happen when
            // host level configuration files change
            do
            {
                ScriptHost newInstance = null;
                try
                {
                    IsRunning = false;

                    // Create a new host config, but keep the host id from existing one
                    _config.HostConfig = new JobHostConfiguration
                    {
                        HostId = _config.HostConfig.HostId
                    };
                    OnInitializeConfig(_config.HostConfig);
                    newInstance = _scriptHostFactory.Create(_config);
                    _traceWriter = newInstance.TraceWriter;

                    newInstance.StartAsync(cancellationToken).Wait();

                    // write any function initialization errors to the log file
                    LogErrors(newInstance);

                    lock (_liveInstances)
                    {
                        _liveInstances.Add(newInstance);
                    }
                    _currentInstance = newInstance;
                    OnHostStarted();

                    // only after ALL initialization is complete do we set this flag
                    IsRunning = true;
                    LastError = null;

                    // Wait for a restart signal. This event will automatically reset.
                    // While we're restarting, it is possible for another restart to be
                    // signaled. That is fine - the restart will be processed immediately
                    // once we get to this line again. The important thing is that these
                    // restarts are only happening on a single thread.
                    WaitHandle.WaitAny(new WaitHandle[] 
                    {
                        cancellationToken.WaitHandle,
                        newInstance.RestartEvent,
                        _stopEvent
                    });

                    // Orphan the current host instance. We're stopping it, so it won't listen for any new functions
                    // it will finish any currently executing functions and then clean itself up.
                    // Spin around and create a new host instance.
                    Task taskIgnore = Orphan(newInstance);
                }
                catch (Exception ex)
                {
                    IsRunning = false;
                    LastError = ex;

                    // We need to keep the host running, so we catch and log any errors
                    // then restart the host
                    if (_traceWriter != null)
                    {
                        _traceWriter.Error("A ScriptHost error occurred", ex);
                    }

                    // If a ScriptHost instance was created before the exception was thrown
                    // Orphan and cleanup that instance.
                    if (newInstance != null)
                    {
                        Orphan(newInstance, forceStop: true)
                            .ContinueWith(t =>
                            {
                                if (t.IsFaulted)
                                {
                                    t.Exception.Handle(e => true);
                                }
                            });
                    }

                    // Wait for a short period of time before restarting to
                    // avoid cases where a host level config error might cause
                    // a rapid restart cycle
                    Task.Delay(5000).Wait();
                }
            }
            while (!_stopped && !cancellationToken.IsCancellationRequested);
        }
        public void RunAndBlock(CancellationToken cancellationToken = default(CancellationToken))
        {
            // Start the host and restart it if requested. Host Restarts will happen when
            // host level configuration files change
            do
            {
                ScriptHost newInstance = null;
                try
                {
                    IsRunning = false;

                    // Create a new host config, but keep the host id from existing one
                    _config.HostConfig = new JobHostConfiguration
                    {
                        HostId = _config.HostConfig.HostId
                    };
                    OnInitializeConfig(_config.HostConfig);
                    newInstance  = _scriptHostFactory.Create(_config);
                    _traceWriter = newInstance.TraceWriter;

                    newInstance.StartAsync(cancellationToken).Wait();

                    // write any function initialization errors to the log file
                    LogErrors(newInstance);

                    lock (_liveInstances)
                    {
                        _liveInstances.Add(newInstance);
                    }
                    _currentInstance = newInstance;
                    OnHostStarted();

                    // only after ALL initialization is complete do we set this flag
                    IsRunning = true;
                    LastError = null;

                    // Wait for a restart signal. This event will automatically reset.
                    // While we're restarting, it is possible for another restart to be
                    // signaled. That is fine - the restart will be processed immediately
                    // once we get to this line again. The important thing is that these
                    // restarts are only happening on a single thread.
                    WaitHandle.WaitAny(new WaitHandle[]
                    {
                        cancellationToken.WaitHandle,
                        newInstance.RestartEvent,
                        _stopEvent
                    });

                    // Orphan the current host instance. We're stopping it, so it won't listen for any new functions
                    // it will finish any currently executing functions and then clean itself up.
                    // Spin around and create a new host instance.
                    Task taskIgnore = Orphan(newInstance);
                }
                catch (Exception ex)
                {
                    IsRunning = false;
                    LastError = ex;

                    // We need to keep the host running, so we catch and log any errors
                    // then restart the host
                    if (_traceWriter != null)
                    {
                        _traceWriter.Error("A ScriptHost error occurred", ex);
                    }

                    // If a ScriptHost instance was created before the exception was thrown
                    // Orphan and cleanup that instance.
                    if (newInstance != null)
                    {
                        Orphan(newInstance, forceStop: true)
                        .ContinueWith(t =>
                        {
                            if (t.IsFaulted)
                            {
                                t.Exception.Handle(e => true);
                            }
                        });
                    }

                    // Wait for a short period of time before restarting to
                    // avoid cases where a host level config error might cause
                    // a rapid restart cycle
                    Task.Delay(5000).Wait();
                }
            }while (!_stopped && !cancellationToken.IsCancellationRequested);
        }
Esempio n. 12
0
 public ScriptHost Create(IScriptHostEnvironment environment, IScriptEventManager eventManager, ScriptSettingsManager settingsManager, ScriptHostConfiguration config)
 {
     return(ScriptHost.Create(environment, eventManager, config, settingsManager));
 }