private void ReloadScript()
        {
            // Reset cached function
            _functionLoader.Reset();
            TraceOnPrimaryHost(string.Format(CultureInfo.InvariantCulture, "Script for function '{0}' changed. Reloading.", Metadata.Name), TraceLevel.Info);

            ImmutableArray <Diagnostic> compilationResult = ImmutableArray <Diagnostic> .Empty;
            FunctionSignature           signature         = null;

            try
            {
                ICompilation compilation = _compilationService.GetFunctionCompilation(Metadata);
                compilationResult = compilation.GetDiagnostics();

                signature         = compilation.GetEntryPointSignature(_functionEntryPointResolver);
                compilationResult = ValidateFunctionBindingArguments(signature, _triggerInputName, _inputBindings, _outputBindings, compilationResult.ToBuilder());
            }
            catch (CompilationErrorException exc)
            {
                compilationResult = AddFunctionDiagnostics(compilationResult.AddRange(exc.Diagnostics));
            }

            TraceCompilationDiagnostics(compilationResult, LogTargets.User);

            bool compilationSucceeded = !compilationResult.Any(d => d.Severity == DiagnosticSeverity.Error);

            TraceOnPrimaryHost(string.Format(CultureInfo.InvariantCulture, "Compilation {0}.", compilationSucceeded ? "succeeded" : "failed"), TraceLevel.Info);

            // If the compilation succeeded, AND:
            //  - We haven't cached a function (failed to compile on load), OR
            //  - We're referencing local function types (i.e. POCOs defined in the function) AND Our our function signature has changed
            // Restart our host.
            if (compilationSucceeded &&
                (_functionSignature == null ||
                 (_functionSignature.HasLocalTypeReference || !_functionSignature.Equals(signature))))
            {
                Host.RestartEvent.Set();
            }
        }
Example #2
0
        private async Task <MethodInfo> CreateFunctionTarget(CancellationToken cancellationToken)
        {
            try
            {
                await VerifyPackageReferencesAsync();

                string eventName = string.Format(MetricEventNames.FunctionCompileLatencyByLanguageFormat, _compilationService.Language);
                using (_metricsLogger.LatencyEvent(eventName, _functionMetadata.Name))
                {
                    IDotNetCompilation compilation = await _compilationService.GetFunctionCompilationAsync(Metadata);

                    DotNetCompilationResult compilationResult = await compilation.EmitAsync(cancellationToken);

                    Assembly assembly = compilationResult.Load(Metadata, _metadataResolver, FunctionLogger);

                    FunctionSignature functionSignature = compilation.GetEntryPointSignature(_functionEntryPointResolver, assembly);

                    ImmutableArray <Diagnostic> bindingDiagnostics = ValidateFunctionBindingArguments(functionSignature, _triggerInputName, _inputBindings, _outputBindings, throwIfFailed: true);
                    TraceCompilationDiagnostics(bindingDiagnostics);

                    _compilerErrorCount = 0;

                    // Set our function entry point signature
                    _functionSignature = functionSignature;

                    return(_functionSignature.GetMethod(assembly));
                }
            }
            catch (CompilationErrorException exc)
            {
                ImmutableArray <Diagnostic> diagnostics = AddFunctionDiagnostics(exc.Diagnostics);

                // Here we only need to trace to system logs
                TraceCompilationDiagnostics(diagnostics, LogTargets.System);

                throw new CompilationErrorException(exc.Message, diagnostics);
            }
        }
        public FunctionSignature GetEntryPointSignature(IFunctionEntryPointResolver entryPointResolver)
        {
            EnsureAssemblyOption();

            // Scrape the compiled assembly for entry points
            IList <MethodReference <MethodInfo> > methods =
                _assemblyOption.Value.GetTypes().SelectMany(t =>
                                                            t.GetMethods().Select(m =>
                                                                                  new MethodReference <MethodInfo>(m.Name, m.IsPublic, m))).ToList();

            MethodInfo entryPointReference = entryPointResolver.GetFunctionEntryPoint(methods).Value;

            // For F#, this currently creates a malformed signautre with fewer parameter symbols than parameter names.
            // For validation we only need the parameter names. The implementation of DotNetFunctionSignature copes with the
            // lists having different lengths.
            var parameters = entryPointReference.GetParameters().Select(x => new FunctionParameter(x.Name, x.ParameterType.FullName, x.IsOptional, GetParameterRefKind(x)));
            // For F#, we always set this to true for now.
            bool hasLocalTypeReference = true;

            var signature = new FunctionSignature(entryPointReference.DeclaringType.Name, entryPointReference.Name, parameters.ToImmutableArray(), hasLocalTypeReference);

            return(signature);
        }
        private async Task <MethodInfo> CreateFunctionTarget(CancellationToken cancellationToken)
        {
            try
            {
                await VerifyPackageReferencesAsync();

                string eventName = string.Format(MetricEventNames.FunctionCompileLatencyByLanguageFormat, _compilationService.Language);
                using (_metricsLogger.LatencyEvent(eventName))
                {
                    ICompilation compilation = _compilationService.GetFunctionCompilation(Metadata);

                    Assembly assembly = compilation.EmitAndLoad(cancellationToken);
                    _assemblyLoader.CreateOrUpdateContext(Metadata, assembly, _metadataResolver, TraceWriter);

                    FunctionSignature functionSignature = compilation.GetEntryPointSignature(_functionEntryPointResolver);

                    ImmutableArray <Diagnostic> bindingDiagnostics = ValidateFunctionBindingArguments(functionSignature, _triggerInputName, _inputBindings, _outputBindings, throwIfFailed: true);
                    TraceCompilationDiagnostics(bindingDiagnostics);

                    // Set our function entry point signature
                    _functionSignature = functionSignature;
                    System.Reflection.TypeInfo scriptType = assembly.DefinedTypes
                                                            .FirstOrDefault(t => string.Compare(t.Name, functionSignature.ParentTypeName, StringComparison.Ordinal) == 0);

                    return(_functionEntryPointResolver.GetFunctionEntryPoint(scriptType.DeclaredMethods.ToList()));
                }
            }
            catch (CompilationErrorException exc)
            {
                ImmutableArray <Diagnostic> diagnostics = AddFunctionDiagnostics(exc.Diagnostics);

                // Here we only need to trace to system logs
                TraceCompilationDiagnostics(diagnostics, LogTargets.System);

                throw new CompilationErrorException(exc.Message, diagnostics);
            }
        }