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(); } }
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); } }