Example #1
0
        /// <summary>
        /// Removes the current operation Id from the stack and returns it.
        /// </summary>
        /// <returns>The Operation id that was removed.</returns>
        public long RemoveOperation()
        {
            long removedOperation;

            // we just decrement the position, max speed.
            this.currentOperationPosition--;

            fixed(long *localStack = this.operationStack)
            {
                removedOperation = localStack[this.currentOperationPosition.Position];

                // copy
                CircularArrayPosition cap = this.currentOperationPosition;

                // we already ahve a handle to -1, we need to get to -2
                cap--;
                this.currentId = localStack[cap.Position];

                cap--;
                this.parentId = localStack[cap.Position];
            }

            Diag($"{nameof(CorrelationContext)}.{nameof(this.RemoveOperation)} ID = {removedOperation} POS = {this.currentOperationPosition.Position} Npm2AJtM20M");

            return(removedOperation);
        }
Example #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CorrelationContext"/> struct.
        /// </summary>
        /// <param name="rootSessionId">Creates a new Context with a seeded random first Id.</param>
        public CorrelationContext(long rootSessionId)
        {
            long sid;

            unchecked
            {
                sid = rootSessionId + rng.NextInt64();
            }

            this.currentOperationPosition = new CircularArrayPosition(OPERATIONSTACKSIZE);

            fixed(long *localStack = this.operationStack)
            {
                localStack[0] = sid;
            }

            this.currentOperationPosition++;
            this.currentId = rootSessionId;
            this.parentId  = default(long);
            this.rootId    = sid;
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CorrelationContext"/> struct from the captured correlation context. This context may be from another thread, application domain, process, machine or even application.
        /// </summary>
        /// <param name="capturedContext">The captured context to recreate the operation tree.</param>
        public CorrelationContext(byte[] capturedContext)
        {
            if (capturedContext == null)
            {
                throw new ArgumentNullException(nameof(capturedContext));
            }

            if (capturedContext.Length % OPERATIONIDBYTELENGTH != 0)
            {
                throw new ArgumentException("The captured context is corrupt, it must be a multiple of 8 to resolve operation Ids");
            }

            if (capturedContext.Length > OPERATIONSTACKSIZE * OPERATIONIDBYTELENGTH)
            {
                throw new ArgumentException("The context captured i corrupt and unusable, it is from a different runtime (Too big)");
            }

            this.currentOperationPosition = new CircularArrayPosition(OPERATIONSTACKSIZE);
            this.currentId = default(long);
            this.parentId  = default(long);

            long operationId;
            long rid = BitConverter.ToInt64(capturedContext, 0);

            this.rootId = rid;

            fixed(long *localStack = this.operationStack)
            {
                for (int i = 0; i < capturedContext.Length; i += OPERATIONIDBYTELENGTH)
                {
                    operationId = BitConverter.ToInt64(capturedContext, i);

                    localStack[this.currentOperationPosition.Position] = operationId;
                    this.currentOperationPosition++;

                    // copy
                    CircularArrayPosition parentFinder = this.currentOperationPosition;

                    // if rolled over, we will have a parent.
                    if (parentFinder.TotalTraversal == 1)
                    {
                        this.parentId  = -1;
                        this.currentId = localStack[0];
                    }
                    else if (parentFinder.TotalTraversal == 2)
                    {
                        this.currentId = localStack[1];
                        this.parentId  = localStack[0];
                    }
                    else
                    {
                        // might have traversal and be at [0].
                        // need to use circular array counter;
                        parentFinder--;
                        this.currentId = localStack[parentFinder.Position];

                        parentFinder--;
                        this.parentId = localStack[parentFinder.Position];
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// Captures the current correlation context and returns it.
        /// </summary>
        /// <returns>The captured context.</returns>
        public byte[] Capture()
        {
            byte[] result;
            long   operationId;

            byte[] buffer;

            // compute operationIdString
            if (this.currentOperationPosition.HasRolledOver)
            {
                // the circular array has rolled over, we must assume overwrite, we must also rollover to compute the Id.

                // 0123456789 123456789 123456789
                //               ^ current position (14)
                // we should index as  15, 16, 17 ... 11, 12 ,13 ,

                // use current position in case is at the very end.
                CircularArrayPosition roller = new CircularArrayPosition(OPERATIONSTACKSIZE, this.currentOperationPosition.Position);
                roller++;

                int traversal = this.currentOperationPosition.TotalTraversal > OPERATIONSTACKSIZE
                    ? OPERATIONSTACKSIZE
                    : this.currentOperationPosition.TotalTraversal;

                // allocate result
                result = new byte[traversal * OPERATIONIDBYTELENGTH];

                fixed(long *localStack = this.operationStack)
                {
                    for (int i = 0; i < traversal; i++)
                    {
                        operationId = localStack[roller.Position];
                        buffer      = BitConverter.GetBytes(operationId);

                        int destinationIndex = i * OPERATIONIDBYTELENGTH;

                        Array.Copy(buffer, 0, result, destinationIndex, OPERATIONIDBYTELENGTH);

                        // roll to next operation id;
                        roller++;
                    }
                }
            }
            else
            {
                int position = this.currentOperationPosition.Position;
                result = new byte[position * OPERATIONIDBYTELENGTH];

                fixed(long *localStack = this.operationStack)
                {
                    for (int i = 0; i < position; i++)
                    {
                        operationId = localStack[i];
                        buffer      = BitConverter.GetBytes(operationId);

                        int destinationIndex = i * OPERATIONIDBYTELENGTH;

                        Array.Copy(buffer, 0, result, destinationIndex, OPERATIONIDBYTELENGTH);
                    }
                }
            }

            return(result);
        }