Why NServiceBus OutgoingHeaders is static and not ThreadStatic?

。_饼干妹妹 提交于 2019-12-07 13:24:04

问题


How is NServiceBus maintaining consistency when the outgoing headers is static?

Does it mean if I were to set the outgoing headers for a particular message, it will affect all other outgoing messages since it's a singleton?

namespace NServiceBus.MessageHeaders
{
  [ComVisible(false)]
  public class MessageHeaderManager : IMutateOutgoingTransportMessages
  {
    private static IDictionary<string, string> staticOutgoingHeaders = (IDictionary<string, string>) new Dictionary<string, string>();
    private IUnicastBus bus;
    [ThreadStatic]
    private static IDictionary<object, IDictionary<string, string>> messageHeaders;
   .
   .
   .
 }

The incoming header seems to be correctly marked as [ThreadStatic] however.

Explain.

========================EDIT==============================

I guess I'm trying to understand because many examples show the code below:

Bus.OutgoingHeaders["Test"] = g.ToString("N");

Which's traced to:

IDictionary<string, string> IBus.OutgoingHeaders
{
  get
  {
    return ExtensionMethods.GetStaticOutgoingHeadersAction();
  }
}

Which's set at:

internal class Bootstrapper : INeedInitialization, IWantToRunWhenConfigurationIsComplete { public MessageHeaderManager Manager { get; set; }

void INeedInitialization.Init()
{
  Configure.Instance.Configurer.ConfigureComponent<MessageHeaderManager>(DependencyLifecycle.SingleInstance);
}

public void Run()
{
  ExtensionMethods.GetHeaderAction = (Func<object, string, string>) ((msg, key) => this.Manager.GetHeader(msg, key));
  ExtensionMethods.SetHeaderAction = (Action<object, string, string>) ((msg, key, val) => this.Manager.SetHeader(msg, key, val));
  ExtensionMethods.GetStaticOutgoingHeadersAction = (Func<IDictionary<string, string>>) (() => this.Manager.GetStaticOutgoingHeaders());
}

}

And of course the GetStaticOutgoingHeaders in the last line above goes to a static field.

I'm trying to figure out how to set the header, for the next message. But if I follow the examples, I end up setting the headers for ALL messages.


回答1:


[Update by Udi] If you want to set a header on a specific message that you're sending, just call the .SetHeader(key, value); method on the message object. The static outgoing headers is useful for process-wide data like who the logged-in user is in a desktop application.[End update]

MessageHeaderManager is a IMutateOutgoingTransportMessages which means it only is concerned with messages on their way out. There are no incoming message headers on display here.

messageHeaders is concerned with headers that are set per-message, like time sent, or anything you would set manually from a message handler.

staticOutgoingHeaders is a place to cache all headers that are the same for every single message out of an endpoint so that their values don't need to be recalculated. This would include things like the source machine name.

If you look into the guts of that MutateOutgoing method, you will see that all of the key/value pairs from both messageHeaders and staticOutgoingHeaders are added to the transportMessage.Headers collection. Additionally, the static ones are added with Headers.Add(key, value) while the thread-static headers are added via Headers[key] = value so that an item from the thread-static collection would override a static header of the same name.

Here's a link to the full source for this class on GitHub, linked by the tag for V4.0.3 (current at time of writing) so hopefully that link won't expire.



来源:https://stackoverflow.com/questions/18411371/why-nservicebus-outgoingheaders-is-static-and-not-threadstatic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!