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?
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.