Sending Service Bus message in Go

Go or GoLang is an open source programming language. It’s a server-side C like language created by Google. I won’t take much or your time to introduce you to the language, but here is a short summary why it’s worth trying.

 

  • Go is open-source, but backed up by Google and used by big companies (Google, Dropbox, Docker, etc.)
  • It is something we know, it resembles C++ and it is easy to read
  • It’s fast, it compiles directly to machine language, no virtual machine in the middle
  • It’s a modern language, with packages instead of classes
  • Unlike many older languages, Go is designed to work in parallel

The easiest way

I found a package on github: https://github.com/michaelbironneau/asbclient. I needed to modify it a bit to work properly, so I forked that into my repo: https://github.com/mikuam/asbclient.

I found an existing sample and provided my credentials.

package main

import (
	"fmt"
	"log"

	"github.com/michaelbironneau/asbclient"
)

func main() {

	i := 0
	log.Printf("Send: %d", i)

	namespace := "bialecki"
	keyname := "RootManageSharedAccessKey"
	keyvalue := "[SharedAccessKeyValue]"

	client := asbclient.New(asbclient.Topic, namespace, keyname, keyvalue)

	err := client.Send("go_testing", &asbclient.Message{
		Body: []byte(fmt.Sprintf("message %d", i)),
	})

	if err != nil {
		log.Printf("Send error: %s", err)
	} else {
		log.Printf("Sent: %d", i)
	}
}

And result can be seen very fast:

Receiving Service Bus message is also trivial with this package and takes only a few lines of code. It looks like this:

package main

import (
	"log"

	"github.com/mikuam/asbclient"
)

func main() {

	namespace := "bialecki"
	keyname := "RootManageSharedAccessKey"
	keyvalue := "[SharedAccessKeyValue]"

	client := asbclient.New(asbclient.Queue, namespace, keyname, keyvalue)
	log.Printf("Peeking...")

	for {
		msg, err := client.PeekLockMessage("go_testing", 30)

		if err != nil {
			log.Printf("Peek error: %s", err)
		} else {
			log.Printf("Peeked message: '%s'", string(msg.Body))
			err = client.DeleteMessage(msg)
			if err != nil {
				log.Printf("Delete error: %s", err)
			}
		}
	}
}

It works, simple as that. So…

How fast is it?

Let’s say I need to send 1000 messages and receive them. As asbclient package supports only sending messages one by one, I will implement the same logic in .Net Core app. Sending part can look like this:

    public async Task Send1000()
    {
        var queueClient = new QueueClient(ServiceBusConnectionString, "go_testing");
        for (int i = 0; i < 1000; i++)
        {
            await queueClient.SendAsync(new Message(Encoding.UTF8.GetBytes("Message number " + i)));
        }
    }

And receiving part:

    public void ReceiveAll()
    {
        var queueClient = new QueueClient(ServiceBusConnectionString, "go_testing");

        queueClient.RegisterMessageHandler(
            async (message, token) =>
            {
                var messageBody = Encoding.UTF8.GetString(message.Body);

                Console.WriteLine($"Received: {messageBody}, time: {DateTime.Now}");

                await queueClient.CompleteAsync(message.SystemProperties.LockToken);
            },
            new MessageHandlerOptions(async args => Console.WriteLine(args.Exception))
            { MaxConcurrentCalls = 1, AutoComplete = false });
    }

So what are the times for 1000 messages?

Sending messages is faster in .Net Core, but receiving is slightly slower. However sending can be done much faster in .Net Core with batch send. Also receiving in some cases can be done faster, if you can write safe code that can process messages in parallel. Notice that in the last code snippet MaxConcurrentCalls is set to 1, that means reading messages is done synchronously.
Go code can be written faster probably as well. Golang is famous for support for parallel code with its goroutines. Should you go with go for Service Bus? Can’t really say if it’s worth it at this point, but it is definitely possible.

 

All code posted you can find it my github repo, go code itself is here: https://github.com/mikuam/Blog/tree/master/Go/src

You can read more about Service Bus in .Net Core in my post: Receiving messages from Azure Service Bus in .Net Core.

Leave a Reply

Your email address will not be published. Required fields are marked *