protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         db.Dispose();
     }
     base.Dispose(disposing);
 }
Example #2
0
 protected virtual void Dispose(bool disposing)
 {
     if (!this.disposed)
     {
         if (disposing)
         {
             _context.Dispose();
         }
     }
     this.disposed = true;
 }
Example #3
0
        void TryProcessIncomingMessage()
        {
            using (var transactionScope = BeginTransaction())
            {
                var transportMessage = receiveMessages.ReceiveMessage();

                if (transportMessage == null)
                {
                    Thread.Sleep(20);
                    return;
                }

                var id    = transportMessage.Id;
                var label = transportMessage.Label;

                MessageContext context = null;

                if (errorTracker.MessageHasFailedMaximumNumberOfTimes(id))
                {
                    log.Error("Handling message {0} has failed the maximum number of times", id);
                    MessageFailedMaxNumberOfTimes(transportMessage, errorTracker.GetErrorText(id));
                    errorTracker.StopTracking(id);

                    try
                    {
                        PoisonMessage(transportMessage);
                    }
                    catch (Exception exceptionWhileRaisingEvent)
                    {
                        log.Error("An exception occurred while raising the PoisonMessage event: {0}",
                                  exceptionWhileRaisingEvent);
                    }
                }
                else
                {
                    try
                    {
                        BeforeTransportMessage(transportMessage);

                        var message = serializeMessages.Deserialize(transportMessage);

                        // successfully deserialized the transport message, let's enter a message context
                        context = MessageContext.Enter(message.Headers);

                        foreach (var logicalMessage in message.Messages)
                        {
                            context.SetLogicalMessage(logicalMessage);

                            try
                            {
                                BeforeMessage(logicalMessage);

                                var typeToDispatch = logicalMessage.GetType();

                                log.Debug("Dispatching message {0}: {1}", id, typeToDispatch);

                                GetDispatchMethod(typeToDispatch).Invoke(this, new[] { logicalMessage });

                                AfterMessage(null, logicalMessage);
                            }
                            catch (Exception exception)
                            {
                                try
                                {
                                    AfterMessage(exception, logicalMessage);
                                }
                                catch (Exception exceptionWhileRaisingEvent)
                                {
                                    log.Error("An exception occurred while raising the AfterMessage event, and an exception occurred some time before that as well. The first exception was this: {0}. And then, when raising the AfterMessage event (including the details of the first error), this exception occurred: {1}",
                                              exception, exceptionWhileRaisingEvent);
                                }
                                throw;
                            }
                            finally
                            {
                                context.ClearLogicalMessage();
                            }
                        }

                        AfterTransportMessage(null, transportMessage);
                    }
                    catch (Exception exception)
                    {
                        log.Debug("Handling message {0} ({1}) has failed", label, id);
                        try
                        {
                            AfterTransportMessage(exception, transportMessage);
                        }
                        catch (Exception exceptionWhileRaisingEvent)
                        {
                            log.Error("An exception occurred while raising the AfterTransportMessage event, and an exception occurred some time before that as well. The first exception was this: {0}. And then, when raising the AfterTransportMessage event (including the details of the first error), this exception occurred: {1}",
                                      exception, exceptionWhileRaisingEvent);
                        }
                        errorTracker.TrackDeliveryFail(id, exception);
                        if (context != null)
                        {
                            context.Dispose();                  //< dispose it if we entered
                        }
                        throw;
                    }
                }

                transactionScope.Complete();
                if (context != null)
                {
                    context.Dispose();                  //< dispose it if we entered
                }
                errorTracker.StopTracking(id);
            }
        }
Example #4
0
        void DoTry()
        {
            var transportMessage = receiveMessages.ReceiveMessage(TransactionContext.Current);

            if (transportMessage == null)
            {
                // to back off and relax when there's no messages to process, we do this
                nullMessageReceivedBackoffHelper.Wait();
                return;
            }

            nullMessageReceivedBackoffHelper.Reset();

            var id    = transportMessage.Id;
            var label = transportMessage.Label;

            MessageContext context = null;

            if (id == null)
            {
                HandlePoisonMessage(id, transportMessage);
                return;
            }

            if (errorTracker.MessageHasFailedMaximumNumberOfTimes(id))
            {
                HandlePoisonMessage(id, transportMessage);
                errorTracker.StopTracking(id);
                return;
            }

            Exception transportMessageExceptionOrNull = null;

            try
            {
                BeforeTransportMessage(transportMessage);

                // Populate rebus-msg-id, if not set, from transport-level-id
                if (!transportMessage.Headers.ContainsKey(Headers.MessageId))
                {
                    transportMessage.Headers[Headers.MessageId] = transportMessage.Id;
                }

                using (var scope = BeginTransaction())
                {
                    var message = serializeMessages.Deserialize(transportMessage);
                    // successfully deserialized the transport message, let's enter a message context
                    context = MessageContext.Establish(message.Headers);
                    MessageContextEstablished(context);

                    var unitsOfWork = unitOfWorkManagers.Select(u => u.Create())
                                      .Where(u => !ReferenceEquals(null, u))
                                      .ToArray(); //< remember to invoke the chain here :)

                    try
                    {
                        foreach (var logicalMessage in message.Messages.Select(MutateIncoming))
                        {
                            context.SetLogicalMessage(logicalMessage);

                            Exception logicalMessageExceptionOrNull = null;
                            try
                            {
                                BeforeMessage(logicalMessage);

                                var typeToDispatch = logicalMessage.GetType();

                                messageLogger.LogReceive(id, logicalMessage);

                                try
                                {
                                    var dispatchMethod = GetDispatchMethod(typeToDispatch);
                                    var parameters     = new[] { logicalMessage };
                                    dispatchMethod.Invoke(this, parameters);
                                }
                                catch (TargetInvocationException tie)
                                {
                                    var exception = tie.InnerException;
                                    exception.PreserveStackTrace();
                                    throw exception;
                                }
                            }
                            catch (Exception exception)
                            {
                                logicalMessageExceptionOrNull = exception;
                                throw;
                            }
                            finally
                            {
                                try
                                {
                                    AfterMessage(logicalMessageExceptionOrNull, logicalMessage);
                                }
                                catch (Exception exceptionWhileRaisingEvent)
                                {
                                    if (logicalMessageExceptionOrNull != null)
                                    {
                                        log.Error(
                                            "An exception occurred while raising the AfterMessage event, and an exception occurred some" +
                                            " time before that as well. The first exception was this: {0}. And then, when raising the" +
                                            " AfterMessage event (including the details of the first error), this exception occurred: {1}",
                                            logicalMessageExceptionOrNull, exceptionWhileRaisingEvent);
                                    }
                                    else
                                    {
                                        log.Error("An exception occurred while raising the AfterMessage event: {0}",
                                                  exceptionWhileRaisingEvent);
                                    }
                                }

                                context.ClearLogicalMessage();
                            }
                        }

                        foreach (var unitOfWork in unitsOfWork)
                        {
                            try
                            {
                                unitOfWork.Commit();
                            }
                            catch (Exception exception)
                            {
                                throw new UnitOfWorkCommitException(exception, unitOfWork);
                            }
                        }
                    }
                    catch
                    {
                        foreach (var unitOfWork in unitsOfWork)
                        {
                            try
                            {
                                unitOfWork.Abort();
                            }
                            catch (Exception abortException)
                            {
                                log.Warn("An error occurred while aborting the unit of work {0}: {1}",
                                         unitOfWork, abortException);
                            }
                        }
                        throw;
                    }
                    finally
                    {
                        foreach (var unitOfWork in unitsOfWork)
                        {
                            unitOfWork.Dispose();
                        }
                    }

                    if (scope != null)
                    {
                        scope.Complete();
                    }
                }
            }
            catch (Exception exception)
            {
                transportMessageExceptionOrNull = exception;
                log.Debug("Handling message {0} with ID {1} has failed", label, id);
                errorTracker.TrackDeliveryFail(id, exception);
                throw new MessageHandleException(id, exception);
            }
            finally
            {
                try
                {
                    AfterTransportMessage(transportMessageExceptionOrNull, transportMessage);
                }
                catch (Exception exceptionWhileRaisingEvent)
                {
                    if (transportMessageExceptionOrNull != null)
                    {
                        log.Error(
                            "An exception occurred while raising the AfterTransportMessage event, and an exception occurred some" +
                            " time before that as well. The first exception was this: {0}. And then, when raising the" +
                            " AfterTransportMessage event (including the details of the first error), this exception occurred: {1}",
                            transportMessageExceptionOrNull, exceptionWhileRaisingEvent);
                    }
                    else
                    {
                        log.Error("An exception occurred while raising the AfterTransportMessage event: {0}", exceptionWhileRaisingEvent);
                    }
                }

                if (context != null)
                {
                    context.Dispose();                  //< dispose it if we entered
                }
            }

            errorTracker.StopTracking(id);
        }
Example #5
0
        public static void Main(string[] args)
        {
            bool debug   = false;
            bool verbose = false;

            for (int i = 1; i < args.Length; i++)
            {
                string arg = args[i];
                if (arg == "--debug")
                {
                    debug = true;
                }
                else if (arg == "--verbose")
                {
                    verbose = true;
                }
                else if (arg == "--console")
                {
                    AllocConsole();
                }
            }

            CultureInfo.DefaultThreadCurrentCulture   = CultureInfo.InvariantCulture;
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;

            SelfPath        = Assembly.GetExecutingAssembly().Location;
            RootDirectory   = Path.GetDirectoryName(Environment.CurrentDirectory);
            ConfigDirectory = Environment.GetEnvironmentVariable("OLYMPUS_CONFIG");
            if (string.IsNullOrEmpty(ConfigDirectory) || !Directory.Exists(ConfigDirectory))
            {
                ConfigDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Olympus");
            }
            Console.Error.WriteLine(RootDirectory);

            if (Type.GetType("Mono.Runtime") != null)
            {
                // Mono hates HTTPS.
                ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {
                    return(true);
                };
            }

            // Enable TLS 1.2 to fix connecting to GitHub.
            ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

            if (args.Length >= 1 && args[0] == "--uninstall" && PlatformHelper.Is(Platform.Windows))
            {
                new CmdWin32AppUninstall().Run(args.Length >= 2 && args[1] == "--quiet");
                return;
            }

            Process parentProc   = null;
            int     parentProcID = 0;

            TcpListener   listener = new TcpListener(IPAddress.Loopback, 0);
            List <Thread> threads  = new List <Thread>();

            listener.Start();

            Console.WriteLine($"{((IPEndPoint) listener.LocalEndpoint).Port}");

            try {
                parentProc = Process.GetProcessById(parentProcID = int.Parse(args.Last()));
            } catch {
                Console.Error.WriteLine("[sharp] Invalid parent process ID");
            }

            if (debug)
            {
                Debugger.Launch();
                Console.WriteLine(@"""debug""");
            }
            else
            {
                Console.WriteLine(@"""ok""");
            }

            Console.WriteLine(@"null");
            Console.Out.Flush();

            if (parentProc != null)
            {
                Thread killswitch = new Thread(() => {
                    try {
                        while (!parentProc.HasExited && parentProc.Id == parentProcID)
                        {
                            Thread.Yield();
                            Thread.Sleep(1000);
                        }
                        Environment.Exit(0);
                    } catch {
                        Environment.Exit(-1);
                    }
                })
                {
                    Name         = "Killswitch",
                    IsBackground = true
                };
                killswitch.Start();
            }

            Cmds.Init();

            try {
                while ((parentProc != null && !parentProc.HasExited && parentProc.Id == parentProcID) || parentProc == null)
                {
                    TcpClient client = listener.AcceptTcpClient();
                    try {
                        string ep = client.Client.RemoteEndPoint.ToString();
                        Console.Error.WriteLine($"[sharp] New TCP connection: {ep}");

                        client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
                        Stream stream = client.GetStream();

                        MessageContext ctx = new MessageContext();

                        lock (Cache)
                            foreach (Message msg in Cache.Values)
                            {
                                ctx.Reply(msg);
                            }

                        Thread threadW = new Thread(() => {
                            try {
                                using (StreamWriter writer = new StreamWriter(stream, UTF8NoBOM))
                                    WriteLoop(parentProc, ctx, writer, verbose);
                            } catch (Exception e) {
                                if (e is ObjectDisposedException)
                                {
                                    Console.Error.WriteLine($"[sharp] Failed writing to {ep}: {e.GetType()}: {e.Message}");
                                }
                                else
                                {
                                    Console.Error.WriteLine($"[sharp] Failed writing to {ep}: {e}");
                                }
                                client.Close();
                            } finally {
                                ctx.Dispose();
                            }
                        })
                        {
                            Name         = $"Write Thread for Connection {ep}",
                            IsBackground = true
                        };

                        Thread threadR = new Thread(() => {
                            try {
                                using (StreamReader reader = new StreamReader(stream, UTF8NoBOM))
                                    ReadLoop(parentProc, ctx, reader, verbose);
                            } catch (Exception e) {
                                if (e is ObjectDisposedException)
                                {
                                    Console.Error.WriteLine($"[sharp] Failed reading from {ep}: {e.GetType()}: {e.Message}");
                                }
                                else
                                {
                                    Console.Error.WriteLine($"[sharp] Failed reading from {ep}: {e}");
                                }
                                client.Close();
                            } finally {
                                ctx.Dispose();
                            }
                        })
                        {
                            Name         = $"Read Thread for Connection {ep}",
                            IsBackground = true
                        };

                        threads.Add(threadW);
                        threads.Add(threadR);
                        threadW.Start();
                        threadR.Start();
                    } catch (ThreadAbortException) {
                    } catch (Exception e) {
                        Console.Error.WriteLine($"[sharp] Failed listening for TCP connection:\n{e}");
                        client.Close();
                    }
                }
            } catch (ThreadAbortException) {
            } catch (Exception e) {
                Console.Error.WriteLine($"[sharp] Failed listening for TCP connection:\n{e}");
            }

            Console.Error.WriteLine("[sharp] Goodbye");
        }
Example #6
0
        public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
                                                IBasicProperties properties, byte[] body)
        {
            Task.Run(async() =>
            {
                ExceptionDispatchInfo exception = null;
                MessageContext context          = null;
                HandlingResult handlingResult   = null;
                try
                {
                    try
                    {
                        context = new MessageContext
                        {
                            DependencyResolver = dependencyResolver,
                            Queue      = queueName,
                            RoutingKey = routingKey,
                            Properties = properties
                        };

                        await DispatchMesage(context, body);

                        handlingResult = new HandlingResult
                        {
                            ConsumeResponse = ConsumeResponse.Ack,
                            MessageAction   = MessageAction.None
                        };
                    }
                    catch (Exception eDispatch)
                    {
                        exception = ExceptionDispatchInfo.Capture(UnwrapException(eDispatch));
                        logger.HandlerException(eDispatch);
                        try
                        {
                            var exceptionStrategyContext = new ExceptionStrategyContext(context, exception.SourceException);

                            exceptionStrategy.HandleException(exceptionStrategyContext);

                            handlingResult = exceptionStrategyContext.HandlingResult.ToHandlingResult();
                        }
                        catch (Exception eStrategy)
                        {
                            logger.HandlerException(eStrategy);
                        }
                    }
                    try
                    {
                        if (handlingResult == null)
                        {
                            handlingResult = new HandlingResult
                            {
                                ConsumeResponse = ConsumeResponse.Nack,
                                MessageAction   = MessageAction.None
                            };
                        }
                        await RunCleanup(context, handlingResult);
                    }
                    catch (Exception eCleanup)
                    {
                        logger.HandlerException(eCleanup);
                    }
                }
                finally
                {
                    try
                    {
                        if (handlingResult == null)
                        {
                            handlingResult = new HandlingResult
                            {
                                ConsumeResponse = ConsumeResponse.Nack,
                                MessageAction   = MessageAction.None
                            };
                        }
                        await worker.Respond(deliveryTag, handlingResult.ConsumeResponse);
                    }
                    catch (Exception eRespond)
                    {
                        logger.HandlerException(eRespond);
                    }
                    try
                    {
                        if (context != null)
                        {
                            context.Dispose();
                        }
                    }
                    catch (Exception eDispose)
                    {
                        logger.HandlerException(eDispose);
                    }
                }
            });
        }
Example #7
0
        void DoTry()
        {
            var transportMessage = receiveMessages.ReceiveMessage(TransactionContext.Current);

            if (transportMessage == null)
            {
                // to back off and relax then there's no messages to process, we do this
                successiveNullMessagesReceived++;
                var sleepTimeIndex = Math.Min(nullMessageSleepTimes.Length - 1, successiveNullMessagesReceived);
                var timeToSleep    = nullMessageSleepTimes[sleepTimeIndex];
                Thread.Sleep(timeToSleep);
                return;
            }

            successiveNullMessagesReceived = 0;

            var id    = transportMessage.Id;
            var label = transportMessage.Label;

            MessageContext context = null;

            if (id == null)
            {
                HandlePoisonMessage(id, transportMessage);
                return;
            }

            if (errorTracker.MessageHasFailedMaximumNumberOfTimes(id))
            {
                HandlePoisonMessage(id, transportMessage);
                errorTracker.StopTracking(id);
                return;
            }

            Exception transportMessageExceptionOrNull = null;

            try
            {
                BeforeTransportMessage(transportMessage);

                using (var scope = BeginTransaction())
                {
                    var message = serializeMessages.Deserialize(transportMessage);
                    // successfully deserialized the transport message, let's enter a message context
                    context = MessageContext.Establish(message.Headers);
                    MessageContextEstablished(context);

                    var unitsOfWork = unitOfWorkManagers.Select(u => u.Create())
                                      .Where(u => !ReferenceEquals(null, u))
                                      .ToArray(); //< remember to invoke the chain here :)

                    try
                    {
                        foreach (var logicalMessage in message.Messages.Select(MutateIncoming))
                        {
                            context.SetLogicalMessage(logicalMessage);

                            Exception logicalMessageExceptionOrNull = null;
                            try
                            {
                                BeforeMessage(logicalMessage);

                                var typeToDispatch = logicalMessage.GetType();

                                log.Debug("Dispatching message {0}: {1}", id, typeToDispatch);

                                GetDispatchMethod(typeToDispatch)
                                .Invoke(this, new[] { logicalMessage });
                            }
                            catch (Exception exception)
                            {
                                logicalMessageExceptionOrNull = exception;
                                throw;
                            }
                            finally
                            {
                                try
                                {
                                    AfterMessage(logicalMessageExceptionOrNull, logicalMessage);
                                }
                                catch (Exception exceptionWhileRaisingEvent)
                                {
                                    if (logicalMessageExceptionOrNull != null)
                                    {
                                        log.Error(
                                            "An exception occurred while raising the AfterMessage event, and an exception occurred some" +
                                            " time before that as well. The first exception was this: {0}. And then, when raising the" +
                                            " AfterMessage event (including the details of the first error), this exception occurred: {1}",
                                            logicalMessageExceptionOrNull, exceptionWhileRaisingEvent);
                                    }
                                    else
                                    {
                                        log.Error("An exception occurred while raising the AfterMessage event: {0}",
                                                  exceptionWhileRaisingEvent);
                                    }
                                }

                                context.ClearLogicalMessage();
                            }
                        }

                        foreach (var unitOfWork in unitsOfWork)
                        {
                            unitOfWork.Commit();
                        }
                    }
                    catch
                    {
                        foreach (var unitOfWork in unitsOfWork)
                        {
                            try
                            {
                                unitOfWork.Abort();
                            }
                            catch (Exception abortException)
                            {
                                log.Warn("An error occurred while aborting the unit of work {0}: {1}",
                                         unitOfWork, abortException);
                            }
                        }
                        throw;
                    }
                    finally
                    {
                        foreach (var unitOfWork in unitsOfWork)
                        {
                            unitOfWork.Dispose();
                        }
                    }

                    if (scope != null)
                    {
                        scope.Complete();
                    }
                }
            }
            catch (Exception exception)
            {
                transportMessageExceptionOrNull = exception;
                log.Debug("Handling message {0} ({1}) has failed", label, id);
                errorTracker.TrackDeliveryFail(id, exception);
                throw;
            }
            finally
            {
                try
                {
                    AfterTransportMessage(transportMessageExceptionOrNull, transportMessage);
                }
                catch (Exception exceptionWhileRaisingEvent)
                {
                    if (transportMessageExceptionOrNull != null)
                    {
                        log.Error(
                            "An exception occurred while raising the AfterTransportMessage event, and an exception occurred some" +
                            " time before that as well. The first exception was this: {0}. And then, when raising the" +
                            " AfterTransportMessage event (including the details of the first error), this exception occurred: {1}",
                            transportMessageExceptionOrNull, exceptionWhileRaisingEvent);
                    }
                    else
                    {
                        log.Error("An exception occurred while raising the AfterTransportMessage event: {0}", exceptionWhileRaisingEvent);
                    }
                }

                if (context != null)
                {
                    context.Dispose();                  //< dispose it if we entered
                }
            }

            errorTracker.StopTracking(id);
        }