//验证Transaction internal void ValidateTransaction(DefaultMessageManager manager, ITransaction parent, ITransaction transaction) { if (transaction.Standalone) { IList <IMessage> children = transaction.Children; int len = children.Count; for (int i = 0; i < len; i++) { IMessage message = children[i]; if (message is ITransaction) { ValidateTransaction(manager, transaction, message as ITransaction); } } if (!transaction.IsCompleted() && transaction is DefaultTransaction) { MarkAsNotCompleted(transaction as DefaultTransaction); } else if (!transaction.IsCompleted()) { if (transaction is DefaultForkedTransaction) { LinkAsRunAway(manager, transaction as DefaultForkedTransaction); } else if (transaction is DefaultTaggedTransaction) { MarkAsRunAway(parent, transaction as DefaultTaggedTransaction); } } } }
private void MigrateMessage(DefaultMessageManager manager, Stack <ITransaction> stack, ITransaction source, ITransaction target, int level) { ITransaction current = level < stack.Count ? stack.ToList()[level] : null; bool shouldKeep = false; foreach (IMessage child in source.Children) { if (child != current) { target.AddChild(child); } else { DefaultTransaction cloned = new DefaultTransaction(current.Type, current.Name, manager); cloned.Timestamp = current.Timestamp; cloned.DurationInMicros = current.DurationInMicros; cloned.AddData(current.Data); cloned.Status = PureCatConstants.SUCCESS; target.AddChild(cloned); MigrateMessage(manager, stack, current, cloned, level + 1); shouldKeep = true; } } source.Children.Clear(); if (shouldKeep) { source.AddChild(current); } }
///<summary> /// return true means the transaction has been flushed. ///</summary> ///<param name="manager"> </param> ///<param name="transaction"> </param> ///<returns> true if message is flushed, false otherwise </returns> public bool End(DefaultMessageManager manager, ITransaction transaction) { if (_mStack.Count != 0) { ITransaction current = _mStack.Pop(); if (transaction == current) { ValidateTransaction(manager, _mStack.Count == 0 ? null : _mStack.Peek(), current); } else { while (transaction != current && _mStack.Count != 0) { ValidateTransaction(manager, _mStack.Peek(), current); current = _mStack.Pop(); } } if (_mStack.Count == 0) { IMessageTree tree = _mTree.Copy(); _mTree.MessageId = null; _mTree.Message = null; manager.Flush(tree); return(true); } } return(false); }
private void AddTransactionChild(DefaultMessageManager manager, IMessage message, ITransaction transaction) { long treePeriod = TrimToHour(_mTree.Message.Timestamp); long messagePeriod = TrimToHour(message.Timestamp - 10 * 1000L); // 10 seconds extra time allowed if (treePeriod < messagePeriod) { TruncateAndFlush(manager, message.Timestamp); } transaction.AddChild(message); }
internal void LinkAsRunAway(DefaultMessageManager manager, IForkedTransaction transaction) { IEvent @event = new DefaultEvent(PureCatConstants.TYPE_REMOTE_CALL, "RunAway"); @event.AddData(transaction.ForkedMessageId, $"{transaction.Type}:{transaction.Name}"); @event.Timestamp = transaction.Timestamp; @event.Status = PureCatConstants.SUCCESS; @event.Complete(); transaction.Standalone = true; manager.Add(@event); }
private void TruncateAndFlush(DefaultMessageManager manager, long timestamp) { IMessageTree tree = _mTree; Stack <ITransaction> stack = _mStack; IMessage message = tree.Message; if (message is DefaultTransaction) { if (tree.MessageId == null) { tree.MessageId = manager.NextMessageId(); } string rootId = tree.RootMessageId; string childId = manager.NextMessageId(); DefaultTransaction source = message as DefaultTransaction; DefaultTransaction target = new DefaultTransaction(source.Type, source.Name, manager); target.Timestamp = source.Timestamp; target.DurationInMicros = source.DurationInMicros; target.AddData(source.Data); target.Status = PureCatConstants.SUCCESS; MigrateMessage(manager, stack, source, target, 1); var list = stack.ToList(); for (int i = list.Count - 1; i >= 0; i--) { DefaultTransaction tran = list[i] as DefaultTransaction; tran.Timestamp = timestamp; tran.DurationInMicros = -1; } IEvent next = new DefaultEvent(PureCatConstants.TYPE_REMOTE_CALL, "Next"); next.AddData(childId); next.Status = PureCatConstants.SUCCESS; target.AddChild(next); IMessageTree t = tree.Copy(); t.Message = target; _mTree.MessageId = childId; _mTree.ParentMessageId = tree.MessageId; _mTree.RootMessageId = rootId ?? tree.MessageId; manager.Flush(t); } }
/// <summary> /// 添加Event和Heartbeat /// </summary> /// <param name="manager"> </param> /// <param name="message"> </param> public void Add(DefaultMessageManager manager, IMessage message) { if ((_mStack.Count == 0)) { var tree = _mTree.Copy(); tree.MessageId = manager.NextMessageId(); tree.Message = message; manager.Flush(tree); } else { var entry = _mStack.Peek(); entry.AddChild(message); } }
public Context(DefaultMessageManager manager, string domain, string hostName, string ipAddress) { _manager = manager; _mTree = new DefaultMessageTree(); _mStack = new Stack <ITransaction>(); var thread = Thread.CurrentThread; var groupName = Thread.GetDomain().FriendlyName; _mTree.ThreadGroupName = groupName; _mTree.ThreadId = thread.ManagedThreadId.ToString(CultureInfo.InvariantCulture); _mTree.ThreadName = thread.Name; _mTree.Domain = domain; _mTree.HostName = hostName; _mTree.IpAddress = ipAddress; }
/// <summary> /// 添加transaction /// </summary> /// <param name="manager"> </param> /// <param name="transaction"> </param> public void Start(DefaultMessageManager manager, ITransaction transaction, bool forked) { if (_mStack.Count != 0) { if (!(transaction is DefaultForkedTransaction)) { ITransaction parent = _mStack.Peek(); AddTransactionChild(manager, transaction, parent); } } else { _mTree.Message = transaction; } if (!forked) { _mStack.Push(transaction); } }
///<summary> /// return true means the transaction has been flushed. ///</summary> ///<param name="manager"> </param> ///<param name="transaction"> </param> ///<returns> true if message is flushed, false otherwise </returns> public bool End(DefaultMessageManager manager, ITransaction transaction) { if (_mStack.Count != 0) { ITransaction current = _mStack.Pop(); if (transaction == current) { ValidateTransaction(manager, _mStack.Count == 0 ? null : _mStack.Peek(), current); } else { while (transaction != current && _mStack.Count != 0) { ValidateTransaction(manager, _mStack.Peek(), current); current = _mStack.Pop(); } } if (_mStack.Count == 0) { IMessageTree tree = _mTree.Copy(); _mTree.MessageId = null; _mTree.Message = null; manager.Flush(tree); return true; } } return false; }
private void MigrateMessage(DefaultMessageManager manager, Stack<ITransaction> stack, ITransaction source, ITransaction target, int level) { ITransaction current = level < stack.Count ? stack.ToList()[level] : null; bool shouldKeep = false; foreach (IMessage child in source.Children) { if (child != current) { target.AddChild(child); } else { DefaultTransaction cloned = new DefaultTransaction(current.Type, current.Name, manager); cloned.Timestamp = current.Timestamp; cloned.DurationInMicros = current.DurationInMicros; cloned.AddData(current.Data); cloned.Status = PureCatConstants.SUCCESS; target.AddChild(cloned); MigrateMessage(manager, stack, current, cloned, level + 1); shouldKeep = true; } } source.Children.Clear(); if (shouldKeep) { source.AddChild(current); } }
private void TruncateAndFlush(DefaultMessageManager manager, long timestamp) { IMessageTree tree = _mTree; Stack<ITransaction> stack = _mStack; IMessage message = tree.Message; if (message is DefaultTransaction) { if (tree.MessageId == null) { tree.MessageId = manager.NextMessageId(); } string rootId = tree.RootMessageId; string childId = manager.NextMessageId(); DefaultTransaction source = message as DefaultTransaction; DefaultTransaction target = new DefaultTransaction(source.Type, source.Name, manager); target.Timestamp = source.Timestamp; target.DurationInMicros = source.DurationInMicros; target.AddData(source.Data); target.Status = PureCatConstants.SUCCESS; MigrateMessage(manager, stack, source, target, 1); var list = stack.ToList(); for (int i = list.Count - 1; i >= 0; i--) { DefaultTransaction tran = list[i] as DefaultTransaction; tran.Timestamp = timestamp; tran.DurationInMicros = -1; } IEvent next = new DefaultEvent(PureCatConstants.TYPE_REMOTE_CALL, "Next"); next.AddData(childId); next.Status = PureCatConstants.SUCCESS; target.AddChild(next); IMessageTree t = tree.Copy(); t.Message = target; _mTree.MessageId = childId; _mTree.ParentMessageId = tree.MessageId; _mTree.RootMessageId = rootId ?? tree.MessageId; manager.Flush(t); } }
private void AddTransactionChild(DefaultMessageManager manager, IMessage message, ITransaction transaction) { long treePeriod = TrimToHour(_mTree.Message.Timestamp); long messagePeriod = TrimToHour(message.Timestamp - 10 * 1000L); // 10 seconds extra time allowed if (treePeriod < messagePeriod) { TruncateAndFlush(manager, message.Timestamp); } transaction.AddChild(message); }
//验证Transaction internal void ValidateTransaction(DefaultMessageManager manager, ITransaction parent, ITransaction transaction) { if (transaction.Standalone) { IList<IMessage> children = transaction.Children; int len = children.Count; for (int i = 0; i < len; i++) { IMessage message = children[i]; if (message is ITransaction) { ValidateTransaction(manager, transaction, message as ITransaction); } } if (!transaction.IsCompleted() && transaction is DefaultTransaction) { MarkAsNotCompleted(transaction as DefaultTransaction); } else if (!transaction.IsCompleted()) { if (transaction is DefaultForkedTransaction) { LinkAsRunAway(manager, transaction as DefaultForkedTransaction); } else if (transaction is DefaultTaggedTransaction) { MarkAsRunAway(parent, transaction as DefaultTaggedTransaction); } } } }
internal void LinkAsRunAway(DefaultMessageManager manager, IForkedTransaction transaction) { IEvent @event = new DefaultEvent(PureCatConstants.TYPE_REMOTE_CALL, "RunAway"); @event.AddData(transaction.ForkedMessageId, $"{transaction.Type}:{transaction.Name}"); @event.Timestamp = transaction.Timestamp; @event.Status = PureCatConstants.SUCCESS; @event.Complete(); transaction.Standalone = true; manager.Add(@event); }
/// <summary> /// 添加transaction /// </summary> /// <param name="manager"> </param> /// <param name="transaction"> </param> public void Start(DefaultMessageManager manager, ITransaction transaction, bool forked) { if (_mStack.Count != 0) { if (!(transaction is DefaultForkedTransaction)) { ITransaction parent = _mStack.Peek(); AddTransactionChild(manager, transaction, parent); } } else { _mTree.Message = transaction; } if (!forked) { _mStack.Push(transaction); } }
/// <summary> /// 添加Event和Heartbeat /// </summary> /// <param name="manager"> </param> /// <param name="message"> </param> public void Add(DefaultMessageManager manager, IMessage message) { if ((_mStack.Count == 0)) { IMessageTree tree = _mTree.Copy(); tree.MessageId = manager.NextMessageId(); tree.Message = message; manager.Flush(tree); } else { ITransaction entry = _mStack.Peek(); entry.AddChild(message); } }