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

Do not recopy the memory over and over when accessing the body #19985

Closed
wants to merge 1 commit into from

Conversation

danielmarbach
Copy link
Contributor

At the moment accessing the Body method translates the annotated message over and over again into the binary data structure. That seems to be a surprising and expensive side effect for a seemingly harmless property access.

All SDK Contribution checklist:

This checklist is used to make sure that common guidelines for a pull request are followed.

  • Please open PR in Draft mode if it is:
    • Work in progress or not intended to be merged.
    • Encountering multiple pipeline failures and working on fixes.
  • If an SDK is being regenerated based on a new swagger spec, a link to the pull request containing these swagger spec changes has been included above.
  • I have read the contribution guidelines.
  • The pull request does not introduce breaking changes.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

SDK Generation Guidelines

  • The generate.cmd file for the SDK has been updated with the version of AutoRest, as well as the commitid of your swagger spec or link to the swagger spec, used to generate the code. (Track 2 only)
  • The *.csproj and AssemblyInfo.cs files have been updated with the new version of the SDK. Please double check nuget.org current release version.

Additional management plane SDK specific contribution checklist:

Note: Only applies to Microsoft.Azure.Management.[RP] or Azure.ResourceManager.[RP]

  • Include updated management metadata.
  • Update AzureRP.props to add/remove version info to maintain up to date API versions.

Management plane SDK Troubleshooting

  • If this is very first SDK for a services and you are adding new service folders directly under /SDK, please add new service label and/or contact assigned reviewer.
  • If the check fails at the Verify Code Generation step, please ensure:
    • Do not modify any code in generated folders.
    • Do not selectively include/remove generated files in the PR.
    • Do use generate.ps1/cmd to generate this PR instead of calling autorest directly.
      Please pay attention to the @microsoft.csharp version output after running generate.ps1. If it is lower than current released version (2.3.82), please run it again as it should pull down the latest version,

Old outstanding PR cleanup

Please note:
If PRs (including draft) has been out for more than 60 days and there are no responses from our query or followups, they will be closed to maintain a concise list for our reviewers.

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

ghost commented Mar 31, 2021

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 Mar 31, 2021
@@ -46,6 +49,8 @@ public ServiceBusMessage(ReadOnlyMemory<byte> body)
{
AmqpMessageBody amqpBody = new AmqpMessageBody(new ReadOnlyMemory<byte>[] { body });
AmqpMessage = new AmqpAnnotatedMessage(amqpBody);

this.body = new Lazy<BinaryData>(() => AmqpMessage.GetBody(), LazyThreadSafetyMode.ExecutionAndPublication);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used the LazyThreadSafetyMode.ExecutionAndPublication to make sure when it throws the behavior is as before

@@ -36,6 +39,7 @@ internal ServiceBusReceivedMessage(ReadOnlyMemory<byte> body)
internal ServiceBusReceivedMessage(AmqpAnnotatedMessage message)
{
AmqpMessage = message;
body = new Lazy<BinaryData>(() => AmqpMessage.GetBody(), LazyThreadSafetyMode.ExecutionAndPublication);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used the LazyThreadSafetyMode.ExecutionAndPublication to make sure when it throws the behavior is as before

@@ -137,10 +142,11 @@ public ServiceBusMessage(ServiceBusReceivedMessage receivedMessage)
/// </summary>
public BinaryData Body
{
get => AmqpMessage.GetBody();
get => body.Value;
Copy link
Member

@jsquire jsquire Mar 31, 2021

Choose a reason for hiding this comment

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

If the underlying AMQP message body is manipulated, either using this setter or directly after calling GetRawAmqpMessage, those changes wouldn't be reflected here.

We could offset that in the setter, but there's no INotifyPropertyChanged or similar on the AmqpAnnotatedMessage so I think we'd still have a gap. I'm in favor of figuring out how to detect and react to changes.

I think it's potentially misleading to have the simple Body property doing this much active work on every get and would love for us to figure out a caching strategy for it. @JoshLove-msft: Any thoughts? Was this something that was discussed during arch review, by chance?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah because the underlying Annotated message is mutable. Sigh... Still it seems that it is very likely that a user calls body multiple times and isn't aware of the computation and memory costs of that

Copy link
Member

Choose a reason for hiding this comment

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

100% agree. I think that's a valid pattern and the use of a simple Body property sends the message "this is lightweight and safe to call in a tight loop." I think we need to fix this.

Copy link
Member

Choose a reason for hiding this comment

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

We can detect when the entire AmqpAnnotatedMessage is swapped out, but you are right that we can't currently detect if the body setter is used within AmqpAnnotatedMessage. Something to consider is that we can at least optimize the 99% case where there is a single data section in GetBody. We will still need to allocate a new BinaryData instance in this case, but we could at least avoid copying the memory.

Copy link
Contributor Author

@danielmarbach danielmarbach Mar 31, 2021

Choose a reason for hiding this comment

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

I think we could detect that by implementing the getter and setter of the AmqpAnnotatedMessage body with a custom implementation instead of the auto property it would be possible to discover those modifications

Copy link
Member

Choose a reason for hiding this comment

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

There'd have to be public API changes regardless. That's the part where we'll have to drive through architect review.

Copy link
Member

@JoshLove-msft JoshLove-msft Mar 31, 2021

Choose a reason for hiding this comment

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

We can optimize the 99% case without any API changes, so that the property is usually simply wrapping the bytes in BinaryData. For cases, where the body is more than a single data section, I'd expect that users would use the GetRawAmqpMessage method and operate on the AmqpAnnotatedMessage directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have a look at #19996. This whole conversation triggered a crazy idea. We would still need to custom manage the body modifications which I think is doable without modifying the public API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I apologize for the fire hose of PRs

Copy link
Member

Choose a reason for hiding this comment

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

Never apologize for being kind enough to spend your free time helping us out. Your efforts, feedback, ideas, and discussion are very much appreciated.

@danielmarbach danielmarbach marked this pull request as draft March 31, 2021 17:59
@danielmarbach
Copy link
Contributor Author

Closing in favour of #19996

@danielmarbach danielmarbach deleted the body-computation branch April 2, 2021 19:02
azure-sdk pushed a commit to azure-sdk/azure-sdk-for-net that referenced this pull request Sep 19, 2022
Network 2022 05 01 (Azure#20695)

* Adds base for updating Microsoft.Network from version stable/2022-01-01 to version 2022-05-01

* Updates readme

* Updates API version in new specs and examples

* add DisableTcpStateTracking on nic (Azure#19734)

Co-authored-by: Dan Tu <dantu@microsoft.com>

* Adding new VIP Swap APIs to support extension resource design (Azure#19698)

* Adding new VIP Swap APIs to support extension resource design

* fixing validation checks

* minor fix

* Reverting changes

* Minor fix to add a new line

* fix description (Azure#19987)

Co-authored-by: Dan Tu <dantu@microsoft.com>

* Add BillingType Property to ExpressRoutePorts (Azure#19932)

* change port json

* changes

* add Virtual network gateway policy group api (Azure#19766)

* finish update on connection configuration references

* resolve reference error

* finish prettier

* resolve sematic error

* finish update change

* enablePrivateLinkFastPath property for VirtualNetworkGatewayConnection resource (Azure#20050)

* Support for Per Rule Actions in Application Gateway WAF (Azure#20027)

* Adding changes for per rule actions

* Fixing spaces

* prettier fix

* Addressing PR comments

* Address review comments

* Add ColoLocation to ExpressRoutePort result (Azure#20033)

* Add ColoLocation to ExpressRoutePort result

* Fix automation code check error

* Merge from network-2022-05-01

* Revert "Merge from network-2022-05-01"

This reverts commit f0671a040b2bad684921f8f8ad4b53bb0f4b4a93.

Co-authored-by: Jianqi Zhao <jianzhao@microsoft.com>

* DDoS Per IP SKU + Custom Policy Deprecation Swagger PR (Azure#19985)

* initial changes

* example file changes

* new files for new apis

* adding a period

* changing reference

* prettier fixes

* ddos fix

* lint diff fixes

* more lint diff errors

* fixing operation id

* changing bool to string enum

* example changes

* adding 202s as these are long running ops

* examples

Co-authored-by: Manas Chakka <manaschakka@microsoft.com>

* Adding UnhealthyThreshold property to LB health probes, and updated examples with new property (Azure#20001)

* Property to enable/disable OCSP revocation check on client certificate (Azure#20301)

* add new property to enable/disable OCSP revocation check on client certificate for MTLS

* revert breaking change of updating enum property

* Add new parameter asn, geo and expressRouteAdvertise to CustomIPPrefix for new 2022-05-01 nrp sdk version (Azure#20266)

* fix

* fix

* fix

* fix

* fix

* fix

Co-authored-by: Weiheng Li <weihl@microsoft.com>

* Network 2022-05-01 Azure Virtual Network Manager Contributions (Azure#20440)

* Add third NIP enum for avnm security admin config, AllowRulesOnly

* add optional top parameters to various network manager post APIs

* revise all example input subscriptions to all zero guid

* change all top parameter max value to 100

* Revert "change all top parameter max value to 100"

This reverts commit 12943d2f2b91b22f1dae232cb291a8551fedfdca.

Co-authored-by: Jared Gorthy <jaredgorthy@microsoft.com>

* Alpelled waf manifest 05 01 2022 (Azure#20047)

* init

* init

* fix comments

* fix err

* try ref to appgw def

* try ref to appgw def

* try ref to appgw def

* try ref to appgw def

* update example

* update example

* update example

* update state and action

* update state and action

* change ruleset name and add tiers

* cammel case fix

* cammel case fix

* s_ruleid

* s_RuleId

* suppress s_RuleId camel case issue

* suppress s_RuleId camel case issue

* address comments

* address comments

* address comments

* fix typo

* cont fix

* cont fix

* cont fix

* cont fix

* cont fix

* add pageable

* add next link

Co-authored-by: Alon Pelled <alpelled@microsoft.com>

* Add prefixType property to CustomIPPrefix for NRP 2022-05-01 (Azure#20486)

* add prefixType parameter

* add example

* Adding swagger changes for routemaps feature (Azure#20091)

* initial changes for routemaps

* run npm prettier script

* adding examples

* fixing validation errors

* more validations

* more fixes

* trying to fix lint error

* fix for match condition

* renaming ActionType to fix lint

* fix for python sdk generation

* renaming Rule to RouteMapRule

* modify examples to remove vnetroutes from non hub vnet conns

* cleanup

* Added Upper-case transform (Azure#20674)

Co-authored-by: dtuCloud <tudan0103@gmail.com>
Co-authored-by: Dan Tu <dantu@microsoft.com>
Co-authored-by: shnaya434 <67019054+shnaya434@users.noreply.github.com>
Co-authored-by: nimaller <71352534+nimaller@users.noreply.github.com>
Co-authored-by: tyrannicrex <jiaczh@microsoft.com>
Co-authored-by: Jesus Arango <jearango@microsoft.com>
Co-authored-by: Sindhu Aluguvelli <sindhureddy216@gmail.com>
Co-authored-by: Jianqi Zhao <archie.j.zhao@gmail.com>
Co-authored-by: Jianqi Zhao <jianzhao@microsoft.com>
Co-authored-by: Manas Chakka <mchakka@gmail.com>
Co-authored-by: Manas Chakka <manaschakka@microsoft.com>
Co-authored-by: bhavanabheem <109241669+bhavanabheem@users.noreply.github.com>
Co-authored-by: biaogao <biga@microsoft.com>
Co-authored-by: Weiheng Li <weihengli.tj@gmail.com>
Co-authored-by: Weiheng Li <weihl@microsoft.com>
Co-authored-by: jago2136 <42753636+jago2136@users.noreply.github.com>
Co-authored-by: Jared Gorthy <jaredgorthy@microsoft.com>
Co-authored-by: alon-microsoft <31221093+alon-microsoft@users.noreply.github.com>
Co-authored-by: Alon Pelled <alpelled@microsoft.com>
Co-authored-by: Eric Hoffmann <112216215+erichoffmannms@users.noreply.github.com>
Co-authored-by: arganapathy <109313670+arganapathy@users.noreply.github.com>
Co-authored-by: rahulbissa2727 <106511944+rahulbissa2727@users.noreply.github.com>
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