NServiceBus 3.0 - Data Bus

Siempre que usemos algún sistema de mensajería tenemos que adaptarnos al límite de tamaño del mensaje que el sistema es capaz de enviar. Este límite varía dependiendo de la tecnología usada.

En la mayoría de sistemas on-premise no hay mucho problema ya que el tamaño acostumbra a ser suficiente para la mayoría de casos. Por ejemplo, en MSMQ – el transporte por defecto en NServiceBus – el límite es de 4MB.

En sistemas en la nube este límite es notablemente inferior. Algunos ejemplos:

  • Azure Queues: 8KB
  • Azure Service Bus Queues: 64KB
  • Amazon SQS: 64KB

En aquellos casos en los que se requiera un límite mayor ya sea porqué usamos NServiceBus en Azure o bien porqué queremos enviar algún dato de gran tamaño como una imagen o video, podemos hacer uso de la propiedad DataBusProperty.

Al usar esta propiedad haremos saber a NServiceBus que en el momento de enviar el mensaje éste sea interceptado por un MessageMutator – ver en el post anterior – y la propiedad sea serializada y persistida en una carpeta compartida para que sea deserializada en el momento de ser obtenida por el servidor. Una imagen vale más que mil palabras:

WF DataBus

Hacer uso del DataBus es muy simple, básicamente tenemos un mensaje con una propiedad de tipo DataBusProperty:

1
2
3
4
5
public class MessageWithImage : IMessage
{
public string MyProperty { get; set; }
public DataBusProperty Image { get; set; }
}

Posteriormente definimos tanto en el cliente como en el servidor para que NServiceBus use la configuración FileShareDataBus:

1
2
3
4
5
6
7
8
9
10
11
public class Initialization : IWantCustomInitialization
{
public void Init()
{
string basePath = ConfigurationManager.AppSettings["SharedFolder"];
Configure.Instance
.FileShareDataBus(basePath)
.UnicastBus().DoNotAutoSubscribe();
}
}

Enviamos el mensaje et voilà:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Main : IWantToRunAtStartup
{
public IBus Bus { get; set; }
public void Run()
{
var img = Image.FromFile("..\\..\\img\\Tulips.png");
Bus.Send(m =>
{
m.MyProperty = "Message with image file ";
m.Image = new DataBusProperty(img);
});
}
public void Stop()
{
}
}

Tenemos el mensaje en la cola con la referencia al fichero de la carpeta compartida:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" ?>
<Messages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.net/Messages">
<MessageWithImage>
<MyProperty>Message with image file </MyProperty>
<Image>
<Key>2012-01-19_04\cf611fb6-8e31-4543-9db4-08bf51869710</Key>
<HasValue>true</HasValue>
</Image>
</MessageWithImage>
</Messages>



SharedFolder DataBus

El ejemplo puede descargarse de: https://github.com/mserrate/NServiceBus.Samples

Nota: Quiero insistir en que dado el tamaño del que disponemos en sistemas de mensajería on-premise la necesidad de usar el DataBus fuera de casos extraordinarios puede significar que no estamos diseñando correctamente los mensajes.