/// <summary>Adds the exception to the fault list.</summary> /// <param name="exceptionObject">The exception to store.</param> /// <remarks> /// Must be called under lock. /// </remarks> private void AddFaultException(object exceptionObject) { Contract.Requires(exceptionObject != null, "AddFaultException(): Expected a non-null exceptionObject"); // Initialize the exceptions list if necessary. The list should be non-null iff it contains exceptions. var exceptions = m_faultExceptions; if (exceptions == null) { m_faultExceptions = exceptions = new List <ExceptionDispatchInfo>(1); } else { Contract.Assert(exceptions.Count > 0, "Expected existing exceptions list to have > 0 exceptions."); } // Handle Exception by capturing it into an ExceptionDispatchInfo and storing that var exception = exceptionObject as Exception; if (exception != null) { exceptions.Add(ExceptionDispatchInfo.Capture(exception)); } else { // Handle ExceptionDispatchInfo by storing it into the list var edi = exceptionObject as ExceptionDispatchInfo; if (edi != null) { exceptions.Add(edi); } else { // Handle enumerables of exceptions by capturing each of the contained exceptions into an EDI and storing it var exColl = exceptionObject as IEnumerable <Exception>; if (exColl != null) { #if DEBUG int numExceptions = 0; #endif foreach (var exc in exColl) { #if DEBUG Contract.Assert(exc != null, "No exceptions should be null"); numExceptions++; #endif exceptions.Add(ExceptionDispatchInfo.Capture(exc)); } #if DEBUG Contract.Assert(numExceptions > 0, "Collection should contain at least one exception."); #endif } else { // Handle enumerables of EDIs by storing them directly var ediColl = exceptionObject as IEnumerable <ExceptionDispatchInfo>; if (ediColl != null) { exceptions.AddRange(ediColl); #if DEBUG Contract.Assert(exceptions.Count > 0, "There should be at least one dispatch info."); foreach (var tmp in exceptions) { Contract.Assert(tmp != null, "No dispatch infos should be null"); } #endif } // Anything else is a programming error else { throw new ArgumentException(Environment.GetResourceString("TaskExceptionHolder_UnknownExceptionType"), "exceptionObject"); } } } } // If all of the exceptions are ThreadAbortExceptions and/or // AppDomainUnloadExceptions, we do not want the finalization // probe to propagate them, so we consider the holder to be // handled. If a subsequent exception comes in of a different // kind, we will reactivate the holder. for (int i = 0; i < exceptions.Count; i++) { var t = exceptions[i].SourceException.GetType(); if (t != typeof(ThreadAbortException) && t != typeof(AppDomainUnloadedException)) { MarkAsUnhandled(); break; } else if (i == exceptions.Count - 1) { MarkAsHandled(false); } } }
public Map(TextureLookup textures, FlatLookup flats, TextureAnimation animation, World world) { try { this.textures = textures; this.flats = flats; this.animation = animation; this.world = world; var options = world.Options; string name; if (DoomApplication.Instance.IWad == "doom2" || DoomApplication.Instance.IWad == "freedoom2" || DoomApplication.Instance.IWad == "plutonia" || DoomApplication.Instance.IWad == "tnt") { name = "MAP" + options.Map.ToString("00"); } else { name = "E" + options.Episode + "M" + options.Map; } Console.Write("Load map '" + name + "': "); var map = $"MAPS/{name}/"; if (!DoomApplication.Instance.FileSystem.Files().Any(file => file.StartsWith(map))) { throw new Exception("Map '" + name + "' was not found!"); } this.vertices = Vertex.FromWad($"{map}VERTEXES"); this.sectors = Sector.FromWad($"{map}SECTORS", flats); this.sides = SideDef.FromWad($"{map}SIDEDEFS", textures, this.sectors); this.lines = LineDef.FromWad($"{map}LINEDEFS", this.vertices, this.sides); this.segs = Seg.FromWad($"{map}SEGS", this.vertices, this.lines); this.subsectors = Subsector.FromWad($"{map}SSECTORS", this.segs); this.nodes = Node.FromWad($"{map}NODES", this.subsectors); this.things = MapThing.FromWad($"{map}THINGS"); this.blockMap = BlockMap.FromWad($"{map}BLOCKMAP", this.lines); this.reject = Reject.FromWad($"{map}REJECT", this.sectors); this.GroupLines(); this.skyTexture = this.GetSkyTextureByMapName(name); if (DoomApplication.Instance.IWad == "doom2" || DoomApplication.Instance.IWad == "freedoom2" || DoomApplication.Instance.IWad == "plutonia" || DoomApplication.Instance.IWad == "tnt") { if (DoomApplication.Instance.IWad == "plutonia") { this.title = DoomInfo.MapTitles.Plutonia[options.Map - 1]; } else if (DoomApplication.Instance.IWad == "tnt") { this.title = DoomInfo.MapTitles.Tnt[options.Map - 1]; } else { this.title = DoomInfo.MapTitles.Doom2[options.Map - 1]; } } else { this.title = DoomInfo.MapTitles.Doom[options.Episode - 1][options.Map - 1]; } Console.WriteLine("OK"); } catch (Exception e) { Console.WriteLine("Failed"); ExceptionDispatchInfo.Throw(e); } }
public static async Task RunAsync( [EventHubTrigger("%ExecutionEventHubName%", Connection = "EventHubConnectionString")] EventData[] inputEvent, [Queue("%StorageQueueName%", Connection = "StorageConnectionString")] CloudQueue outputQueue, ILogger logger, ExecutionContext context) { var exceptions = new List <Exception>(); foreach (EventData eventData in inputEvent) { try { var messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count); logger.LogInformation($"{context.FunctionName}: {messageBody}"); // AzFunctions will append multiple messages in the same event var messageBodies = messageBody.Split(System.Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); foreach (string message in messageBodies) { var backfillDeviceRequest = JsonConvert.DeserializeObject <Types.BackfillRequest>(message); // We can check for existing overlapping records here to avoid any rare race conditions await Helpers.SqlHelpers.RecordDeviceBackfillRequest(backfillDeviceRequest, logger); await Helpers.IoTHelpers.InvokeDirectMethod(backfillDeviceRequest, logger); await outputQueue.AddMessageAsync( message : new CloudQueueMessage( JsonConvert.SerializeObject(new Types.DataGap() { BatchId = backfillDeviceRequest.BatchId, StartWindow = backfillDeviceRequest.StartWindow, EndWindow = backfillDeviceRequest.EndWindow, GapInSeconds = (backfillDeviceRequest.EndWindow - backfillDeviceRequest.StartWindow).Seconds })), timeToLive : TimeSpan.FromSeconds(Int32.Parse(Environment.GetEnvironmentVariable("DataGapsTTLSeconds"))), initialVisibilityDelay : TimeSpan.FromSeconds(Int32.Parse(Environment.GetEnvironmentVariable("DetectionRetryInvincibleSeconds"))), options : null, operationContext : null); await Task.Yield(); } } catch (Exception e) { exceptions.Add(e); } } // All input events will be processed. // We will rethrow the generated processing exception(s) if (exceptions.Count > 1) { throw new AggregateException(exceptions); } if (exceptions.Count == 1) { ExceptionDispatchInfo.Capture(exceptions.Single()).Throw(); } }
/// <summary> /// Search MagicOnion service from target types. /// </summary> /// <param name="serviceProvider">The service provider is used to resolve dependencies</param> /// <param name="targetTypes">The types to be search for services</param> /// <param name="options">The options for MagicOnion server</param> public static MagicOnionServiceDefinition BuildServerServiceDefinition(IServiceProvider serviceProvider, IEnumerable <Type> targetTypes, MagicOnionOptions options) { var handlers = new HashSet <MethodHandler>(); var streamingHubHandlers = new List <StreamingHubHandler>(); var types = targetTypes .Where(x => typeof(IServiceMarker).IsAssignableFrom(x)) .Where(x => !x.GetTypeInfo().IsAbstract) .Where(x => x.GetCustomAttribute <IgnoreAttribute>(false) == null) .ToArray(); var logger = serviceProvider.GetRequiredService <IMagicOnionLogger>(); logger.BeginBuildServiceDefinition(); var sw = Stopwatch.StartNew(); try { foreach (var classType in types) { var className = classType.Name; if (!classType.GetConstructors().Any(x => x.GetParameters().Length == 0)) { // supports paramaterless constructor after v2.1(DI support). // throw new InvalidOperationException(string.Format("Type needs parameterless constructor, class:{0}", classType.FullName)); } var isStreamingHub = typeof(IStreamingHubMarker).IsAssignableFrom(classType); HashSet <StreamingHubHandler>?tempStreamingHubHandlers = null; if (isStreamingHub) { tempStreamingHubHandlers = new HashSet <StreamingHubHandler>(); } var inheritInterface = classType.GetInterfaces() .First(x => x.IsGenericType && x.GetGenericTypeDefinition() == (isStreamingHub ? typeof(IStreamingHub <,>) : typeof(IService <>))) .GenericTypeArguments[0]; if (!inheritInterface.IsAssignableFrom(classType)) { throw new NotImplementedException($"Type '{classType.FullName}' has no implementation of interface '{inheritInterface.FullName}'."); } var interfaceMap = classType.GetInterfaceMap(inheritInterface); for (int i = 0; i < interfaceMap.TargetMethods.Length; ++i) { var methodInfo = interfaceMap.TargetMethods[i]; var methodName = interfaceMap.InterfaceMethods[i].Name; if (methodInfo.IsSpecialName && (methodInfo.Name.StartsWith("set_") || methodInfo.Name.StartsWith("get_"))) { continue; } if (methodInfo.GetCustomAttribute <IgnoreAttribute>(false) != null) { continue; // ignore } // ignore default methods if (methodName == "Equals" || methodName == "GetHashCode" || methodName == "GetType" || methodName == "ToString" || methodName == "WithOptions" || methodName == "WithHeaders" || methodName == "WithDeadline" || methodName == "WithCancellationToken" || methodName == "WithHost" ) { continue; } // register for StreamingHub if (isStreamingHub && methodName != "Connect") { var streamingHandler = new StreamingHubHandler(classType, methodInfo, new StreamingHubHandlerOptions(options), serviceProvider); if (!tempStreamingHubHandlers !.Add(streamingHandler)) { throw new InvalidOperationException($"Method does not allow overload, {className}.{methodName}"); } continue; } else { // create handler var handler = new MethodHandler(classType, methodInfo, methodName, new MethodHandlerOptions(options), serviceProvider); if (!handlers.Add(handler)) { throw new InvalidOperationException($"Method does not allow overload, {className}.{methodName}"); } } } if (isStreamingHub) { var connectHandler = new MethodHandler(classType, classType.GetMethod("Connect") !, "Connect", new MethodHandlerOptions(options), serviceProvider); if (!handlers.Add(connectHandler)) { throw new InvalidOperationException($"Method does not allow overload, {className}.Connect"); } streamingHubHandlers.AddRange(tempStreamingHubHandlers !); StreamingHubHandlerRepository.RegisterHandler(connectHandler, tempStreamingHubHandlers.ToArray()); IGroupRepositoryFactory factory; var attr = classType.GetCustomAttribute <GroupConfigurationAttribute>(true); if (attr != null) { factory = (IGroupRepositoryFactory)ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider, attr.FactoryType); } else { factory = serviceProvider.GetRequiredService <IGroupRepositoryFactory>(); } StreamingHubHandlerRepository.AddGroupRepository(connectHandler, factory.CreateRepository(options.SerializerOptions, logger)); } } } catch (AggregateException agex) { ExceptionDispatchInfo.Capture(agex.InnerExceptions[0]).Throw(); } var result = new MagicOnionServiceDefinition(handlers.ToArray(), streamingHubHandlers.ToArray()); sw.Stop(); logger.EndBuildServiceDefinition(sw.Elapsed.TotalMilliseconds); return(result); }
public ExceptionHolder(ExceptionDispatchInfo exception) { this.exception = exception; }
protected override void OnHandlerError(CircuitHandler circuitHandler, string handlerMethod, Exception ex) { ExceptionDispatchInfo.Capture(ex).Throw(); }
private static async Task RunProcessAsync( AgentTaskPluginExecutionContext context, string processFileName, string processArguments, Func <Process, CancellationToken, Task> additionalTaskToExecuteWhilstRunningProcess, Action actionOnFailure, CancellationToken cancellationToken) { var processTcs = new TaskCompletionSource <int>(); using (var cancelSource = new CancellationTokenSource()) using (var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, cancelSource.Token)) using (var process = new Process()) { SetProcessStartInfo(process, processFileName, processArguments); process.EnableRaisingEvents = true; process.Exited += (sender, args) => { cancelSource.Cancel(); processTcs.SetResult(process.ExitCode); }; try { context.Debug($"Starting '{process.StartInfo.FileName}' with arguments '{process.StartInfo.Arguments}'..."); process.Start(); } catch (Exception e) { ExceptionDispatchInfo.Capture(e).Throw(); } var output = new List <string>(); Task readLines(string prefix, StreamReader reader) => Task.Run(async() => { string line; while (null != (line = await reader.ReadLineAsync())) { lock (output) { output.Add($"{prefix}{line}"); } } }); Task readStdOut = readLines("stdout: ", process.StandardOutput); Task readStdError = readLines("stderr: ", process.StandardError); // Our goal is to always have the process ended or killed by the time we exit the function. try { using (cancellationToken.Register(() => process.Kill())) { // readStdOut and readStdError should only fail if the process dies // processTcs.Task cannot fail as we only call SetResult on processTcs IEnumerable <Task> tasks = new List <Task> { readStdOut, readStdError, processTcs.Task, additionalTaskToExecuteWhilstRunningProcess(process, linkedSource.Token) }; await Task.WhenAll(tasks); } int exitCode = await processTcs.Task; if (exitCode == 0) { context.Output($"Process exit code: {exitCode}"); foreach (string line in output) { context.Output(line); } } else { throw new Exception($"Process returned non-zero exit code: {exitCode}"); } } catch (Exception e) { actionOnFailure(); foreach (string line in output) { context.Error(line); } ExceptionDispatchInfo.Capture(e).Throw(); } } }
private void MergeOperationThreadProc() { try { Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; } catch (Exception e) { if (_log.IsInfoEnabled) { _log.Info("Unable to elevate the transaction merger thread for " + _parent.Name, e); } } var oomTimer = new Stopwatch(); // this is allocated here to avoid OOM when using it while (true) // this is actually only executed once, except if we are trying to recover from OOM errors { NativeMemory.EnsureRegistered(); try { while (_runTransactions) { if (_operations.IsEmpty) { using (var generalMeter = GeneralWaitPerformanceMetrics.MeterPerformanceRate()) { generalMeter.IncrementCounter(1); _waitHandle.Wait(_shutdown); } _waitHandle.Reset(); } MergeTransactionsOnce(); } return; } catch (OperationCanceledException) { // clean shutdown, nothing to do } catch (Exception e) when(e is OutOfMemoryException) { // this catch block is meant to handle potentially transient errors // in particular, an OOM error is something that we want to recover // we'll handle this by throwing out all the pending transactions, // waiting for 3 seconds and then resuming normal operations if (_log.IsOperationsEnabled) { try { _log.Operations( "OutOfMemoryException happened in the transaction merger, will abort all transactions for the next 3 seconds and then resume operations", e); } catch { // under these conditions, this may throw, but we don't care, we wanna survive (cue music) } } ClearQueueWithException(e); oomTimer.Restart(); while (_runTransactions) { try { var timeSpan = TimeSpan.FromSeconds(3) - oomTimer.Elapsed; if (timeSpan <= TimeSpan.Zero || _waitHandle.Wait(timeSpan, _shutdown) == false) { break; } } catch (ObjectDisposedException) { return; } catch (OperationCanceledException) { return; } ClearQueueWithException(e); } oomTimer.Stop(); // and now we return to the top of the loop and restart } catch (Exception e) { if (_log.IsOperationsEnabled) { _log.Operations( "Serious failure in transaction merging thread, the database must be restarted!", e); } Interlocked.Exchange(ref _edi, ExceptionDispatchInfo.Capture(e)); // cautionary, we make sure that stuff that is waiting on the // queue is notified about this catastrophic3 error and we wait // just a bit more to verify that nothing racy can still get // there while (_runTransactions) { ClearQueueWithException(e); try { _waitHandle.Wait(_shutdown); _waitHandle.Reset(); } catch (ObjectDisposedException) { return; } catch (OperationCanceledException) { return; } } } } void ClearQueueWithException(Exception e) { while (_operations.TryDequeue(out MergedTransactionCommand result)) { result.Exception = e; NotifyOnThreadPool(result); } } }