Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ServiceBus EventSource remove allocations and boxing #27080

Merged
merged 7 commits into from
Apr 2, 2022

Conversation

danielmarbach
Copy link
Contributor

Similar to #26989 but for ServiceBus to make @JoshLove-msft a happy person too.

Contributing to the Azure SDK

Please see our CONTRIBUTING.md if you are not familiar with contributing to this repository or have questions.

For specific information about pull request etiquette and best practices, see this section.

@ghost ghost added Service Bus customer-reported Issues that are reported by GitHub users external to the Azure organization. labels Feb 17, 2022
@ghost
Copy link

ghost commented Feb 17, 2022

Thank you for your contribution @danielmarbach! We will review the pull request and get back to you soon.

@ghost ghost added the Community Contribution Community members are working on the issue label Feb 17, 2022
@jsquire
Copy link
Member

jsquire commented Feb 23, 2022

/azp run net - servicebus - tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jsquire
Copy link
Member

jsquire commented Feb 23, 2022

The test LogsTransactionEvents seems to be the source of failures, though it appears to be flaky rather than outright failing. Might be a timing issue or may be something more involved. I haven't had a chance to dig into it at all.

@danielmarbach
Copy link
Contributor Author

I can also look into it sometime next week. I'm mostly AFK enjoying carnival 🙃

@danielmarbach
Copy link
Contributor Author

Pushed an update

@danielmarbach
Copy link
Contributor Author

Is it possible to rerun the tests here to see if things are still flaky?

@jsquire
Copy link
Member

jsquire commented Mar 16, 2022

/azp run net - servicebus - tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@danielmarbach
Copy link
Contributor Author

Eyeballing it again I think the order of parameters, types as well as the sizes of the parameters should match what we had before. I can explain why it is failing. I pushed now an update the removes the unsafe on one of the Event methods to make sure we have nothing unsafe on the event methods. Other than that I'm a bit clueless what it could be. I need to probably setup the test environment at some point on my machine to get more insights...

@JoshLove-msft
Copy link
Member

/azp run net - servicebus - tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jsquire
Copy link
Member

jsquire commented Mar 17, 2022

Eyeballing it again I think the order of parameters, types as well as the sizes of the parameters should match what we had before. I can explain why it is failing. I pushed now an update the removes the unsafe on one of the Event methods to make sure we have nothing unsafe on the event methods. Other than that I'm a bit clueless what it could be. I need to probably setup the test environment at some point on my machine to get more insights...

Agreed. I've revisited this a couple of times in the last two weeks, and I am at a loss. The results are consistent, though, and show that something in LogsTransactionEvents gets upset. I wonder if this maybe has something to do with TestEventListener rather than the event source itself? Or maybe the Delay used in the test? I haven't been able to dig into those areas yet.

@danielmarbach
Copy link
Contributor Author

One thing I was thinking too is how the nullable long gets marshalled.
https://github.com/Azure/azure-sdk-for-net/pull/27080/files#diff-a04e2e6a1ccc3dcb86a0a74542e67776cef7660d3fe894c533cd8652c97872d1R353
Long requires 8 bytes but the nullable long 16. I wonder if passing them as part of an array behaves different.

@danielmarbach
Copy link
Contributor Author

danielmarbach commented Mar 17, 2022

Narrator: It was a bool who made fool not sleep.

@danielmarbach
Copy link
Contributor Author

danielmarbach commented Mar 17, 2022

This simple repro helped quite a bit

// See https://aka.ms/new-console-template for more information
using System.Diagnostics.Tracing;
using System.Runtime.CompilerServices;

SomeEventSourceListener listener = new SomeEventSourceListener();

SomeEventSource.Log.TransactionDischarged("TransactionId", " AmqpTransactionId", true);

Console.ReadLine();


sealed class SomeEventSourceListener : EventListener
{
    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        if (eventSource.Name.Equals("Some-EventSource"))
        {
            EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All);
        }
    }

    // from https://blogs.msdn.microsoft.com/dotnet/2018/12/04/announcing-net-core-2-2/
    // Called whenever an event is written.
    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        // Write the contents of the event to the console.
        Console.WriteLine($"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventName}");
        for (int i = 0; i < eventData.Payload.Count; i++)
        {
            string payloadString = eventData.Payload[i] != null ? eventData.Payload[i].ToString() : string.Empty;
            Console.WriteLine($"    Name = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\"");
        }
        Console.WriteLine("\n");
    }
}

[EventSource(Name = EventSourceName)]
internal class SomeEventSource : EventSource
{
    private const string EventSourceName = "Some-EventSource";

    internal const int TransactionDischargedEvent = 91;

    protected SomeEventSource()
    {
    }

    public static SomeEventSource Log { get; } = new SomeEventSource();

    [Event(TransactionDischargedEvent, Level = EventLevel.Informational, Message = "AmqpTransactionDischarged for LocalTransactionId: {0} AmqpTransactionId: {1} Rollback: {2}.")]
    public void TransactionDischarged(string transactionId, string amqpTransactionId, bool rollback)
    {
        //WriteEvent(TransactionDischargedEvent, transactionId, amqpTransactionId, rollback);
        TransactionDischargedCore(TransactionDischargedEvent, transactionId, amqpTransactionId, rollback);
    }

    [NonEvent]
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private unsafe void TransactionDischargedCore(int eventId, string transactionId, string amqpTransactionId, bool rollback)
    {
        fixed (char* transactionIdPtr = transactionId)
        fixed (char* amqpTransactionIdPtr = amqpTransactionId)
        {
            var eventPayload = stackalloc EventData[3];

            eventPayload[0].Size = (transactionId.Length + 1) * sizeof(char);
            eventPayload[0].DataPointer = (IntPtr)transactionIdPtr;

            eventPayload[1].Size = (amqpTransactionId.Length + 1) * sizeof(char);
            eventPayload[1].DataPointer = (IntPtr)amqpTransactionIdPtr;

            var rollbackInt = Convert.ToInt32(rollback);
            eventPayload[2].Size = Unsafe.SizeOf<int>();
            eventPayload[2].DataPointer = (IntPtr) Unsafe.AsPointer(ref rollbackInt);

            WriteEventCore(eventId, 3, eventPayload);
        }
    }
}

@danielmarbach
Copy link
Contributor Author

This should now pass (famous last words)

@JoshLove-msft
Copy link
Member

/azp run net - servicebus - tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jsquire
Copy link
Member

jsquire commented Mar 18, 2022

/azp run net - servicebus - tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jsquire
Copy link
Member

jsquire commented Mar 18, 2022

.... and I just realized Josh already ran the tests, so now we get two clean runs. 😄

@danielmarbach
Copy link
Contributor Author

Ping ;)

@JoshLove-msft
Copy link
Member

Ping ;)

Will take a look today - thanks again for your patience @danielmarbach!

Copy link
Member

@JoshLove-msft JoshLove-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @danielmarbach!

@JoshLove-msft JoshLove-msft merged commit a449d59 into Azure:main Apr 2, 2022
@danielmarbach danielmarbach deleted the servicebus-event-source branch July 18, 2022 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community Contribution Community members are working on the issue customer-reported Issues that are reported by GitHub users external to the Azure organization. Service Bus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants