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; 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); } }
private async Task <MethodInfo> CreateFunctionTarget(CancellationToken cancellationToken) { try { await VerifyPackageReferencesAsync(); ICompilation compilation = _compilationService.GetFunctionCompilation(Metadata); FunctionSignature functionSignature = compilation.GetEntryPointSignature(_functionEntryPointResolver); ImmutableArray <Diagnostic> bindingDiagnostics = ValidateFunctionBindingArguments(functionSignature, _triggerInputName, _inputBindings, _outputBindings, throwIfFailed: true); TraceCompilationDiagnostics(bindingDiagnostics); Assembly assembly = compilation.EmitAndLoad(cancellationToken); _assemblyLoader.CreateOrUpdateContext(Metadata, assembly, _metadataResolver, TraceWriter); // Get our function entry point _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 ex) { TraceOnPrimaryHost("Function compilation error", TraceLevel.Error); TraceCompilationDiagnostics(ex.Diagnostics); throw; } }
private void ReloadScript() { // Reset cached function ResetFunctionValue(); TraceWriter.Info(string.Format(CultureInfo.InvariantCulture, "Script for function '{0}' changed. Reloading.", Metadata.Name)); TraceWriter.Info("Compiling function script."); ICompilation compilation = _compilationService.GetFunctionCompilation(Metadata); ImmutableArray <Diagnostic> compilationResult = compilation.GetDiagnostics(); FunctionSignature signature = compilation.GetEntryPointSignature(_functionEntryPointResolver); compilationResult = ValidateFunctionBindingArguments(signature, compilationResult.ToBuilder()); TraceCompilationDiagnostics(compilationResult); bool compilationSucceeded = !compilationResult.Any(d => d.Severity == DiagnosticSeverity.Error); TraceWriter.Info(string.Format(CultureInfo.InvariantCulture, "Compilation {0}.", compilationSucceeded ? "succeeded" : "failed")); // 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(); } }
public async void CompilationService_TestVaildEntryPointResolution() { var serviceInstance = CompilationServiceFactory.CreateService(ScriptTestDataHelper.GetRandomMetadata(), ScriptOptions.Default); ICompilation compilation = await serviceInstance.GetCompilationAsync(); Exception ex = Record.Exception(() => { EntityMethodSignature methodSignature = compilation.GetEntryPointSignature(); }); Assert.Null(ex); }
public async void CompilationService_TestDuplicateEntryPoints(ScriptErrorType errorType) { EntityMetadata metadata = ScriptTestDataHelper.GetRandomMetadata(); metadata.ScriptText = ScriptTestDataHelper.GetInvalidCsxScript(errorType); var serviceInstance = CompilationServiceFactory.CreateService(metadata, ScriptOptions.Default); ICompilation compilation = await serviceInstance.GetCompilationAsync(); ScriptCompilationException ex = Assert.Throws <ScriptCompilationException>(() => { EntityMethodSignature methodSignature = compilation.GetEntryPointSignature(); }); Assert.NotEmpty(ex.CompilationOutput); }
private MethodInfo CreateFunctionTarget(CancellationToken cancellationToken) { MemoryStream assemblyStream = null; MemoryStream pdbStream = null; try { ICompilation compilation = _compilationService.GetFunctionCompilation(Metadata); FunctionSignature functionSignature = compilation.GetEntryPointSignature(_functionEntryPointResolver); ImmutableArray <Diagnostic> bindingDiagnostics = ValidateFunctionBindingArguments(functionSignature, throwIfFailed: true); TraceCompilationDiagnostics(bindingDiagnostics); using (assemblyStream = new MemoryStream()) { using (pdbStream = new MemoryStream()) { compilation.Emit(assemblyStream, pdbStream, cancellationToken); // Check if cancellation was requested while we were compiling, // and if so quit here. cancellationToken.ThrowIfCancellationRequested(); Assembly assembly = Assembly.Load(assemblyStream.GetBuffer(), pdbStream.GetBuffer()); _assemblyLoader.CreateOrUpdateContext(Metadata, assembly, _metadataResolver, TraceWriter); // Get our function entry point _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 ex) { TraceWriter.Error("Function compilation error"); TraceCompilationDiagnostics(ex.Diagnostics); throw; } }
/// <summary> /// Initializes the entry point by compiling the script and loading/saving the assembly /// </summary> /// <param name="assemblyInitType"></param> /// <returns></returns> public async Task InitializeEntryPointAsync() { ICompilationService compilationService = CompilationServiceFactory.CreateService(_entityMetaData, GetScriptOptions(_frameworkReferences)); _compilation = await compilationService.GetCompilationAsync(); _diagnostics = await _compilation.GetDiagnosticsAsync(); IsCompilationSuccessful = !_diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error); CompilationOutput = _diagnostics.Select(m => m.ToString()); if (IsCompilationSuccessful) { try { EntityMethodSignature methodSignature = _compilation.GetEntryPointSignature(); Assembly assembly = await _compilation.EmitAssemblyAsync(); _entryPointMethodInfo = methodSignature.GetMethod(assembly); InitializeAttributes(); Validate(); } catch (Exception ex) { if (ex is ScriptCompilationException scriptEx) { IsCompilationSuccessful = false; if (scriptEx.CompilationOutput.Any()) { CompilationOutput = CompilationOutput.Concat(scriptEx.CompilationOutput); } return; } throw ex; } } }
private async Task ReloadScriptAsync() { // 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)))) { await Host.RestartAsync().ConfigureAwait(false); } }
/// <summary> /// Initializes the entry point from already loaded assembly. /// </summary> /// <param name="asm">Assembly</param> public void InitializeEntryPoint(Assembly asm) { if (asm == null) { throw new ArgumentNullException("Assembly"); } // TODO : We might need to create a factory to get compilation object based on type. _compilation = new SignalCompilation(); // If assembly is present, that means compilation was successful. IsCompilationSuccessful = true; try { EntityMethodSignature methodSignature = _compilation.GetEntryPointSignature(); _entryPointMethodInfo = methodSignature.GetMethod(asm); InitializeAttributes(); } catch (Exception ex) { if (ex is ScriptCompilationException scriptEx) { IsCompilationSuccessful = false; if (scriptEx.CompilationOutput.Any()) { CompilationOutput = CompilationOutput.Concat(scriptEx.CompilationOutput); } return; } throw ex; } }