Alex Ellis f954bf0733 Merge master into breakout_swarm
Signed-off-by: Alex Ellis <alexellis2@gmail.com>
2018-02-01 09:29:54 +00:00

246 lines
5.5 KiB
Go

package stan
////////////////////////////////////////////////////////////////////////////////
// Benchmarks
////////////////////////////////////////////////////////////////////////////////
import (
"fmt"
"sync/atomic"
"testing"
"time"
)
func BenchmarkPublish(b *testing.B) {
b.StopTimer()
// Run a NATS Streaming server
s := RunServer(clusterName)
defer s.Shutdown()
sc := NewDefaultConnection(b)
defer sc.Close()
hw := []byte("Hello World")
b.StartTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
if err := sc.Publish("foo", hw); err != nil {
b.Fatalf("Got error on publish: %v\n", err)
}
}
}
func BenchmarkPublishAsync(b *testing.B) {
b.StopTimer()
// Run a NATS Streaming server
s := RunServer(clusterName)
defer s.Shutdown()
sc := NewDefaultConnection(b)
defer sc.Close()
hw := []byte("Hello World")
ch := make(chan bool)
received := int32(0)
ah := func(guid string, err error) {
if err != nil {
b.Fatalf("Received an error in ack callback: %v\n", err)
}
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
ch <- true
}
}
b.StartTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
if _, err := sc.PublishAsync("foo", hw, ah); err != nil {
//fmt.Printf("Client status %v, Server status %v\n", s.nc.Status(), (sc.(*conn)).nc.Status())
fmt.Printf("len(ackmap) = %d\n", len(sc.(*conn).pubAckMap))
b.Fatalf("Error from PublishAsync: %v\n", err)
}
}
err := WaitTime(ch, 10*time.Second)
if err != nil {
fmt.Printf("sc error is %v\n", sc.(*conn).nc.LastError())
b.Fatal("Timed out waiting for ack messages")
} else if atomic.LoadInt32(&received) != int32(b.N) {
b.Fatalf("Received: %d", received)
}
// msgs, bytes, _ := sc.(*conn).ackSubscription.MaxPending()
// fmt.Printf("max pending msgs:%d bytes:%d\n", msgs, bytes)
}
func BenchmarkSubscribe(b *testing.B) {
b.StopTimer()
// Run a NATS Streaming server
s := RunServer(clusterName)
defer s.Shutdown()
sc := NewDefaultConnection(b)
defer sc.Close()
hw := []byte("Hello World")
pch := make(chan bool)
// Queue up all the messages. Keep this outside of the timing.
for i := 0; i < b.N; i++ {
if i == b.N-1 {
// last one
sc.PublishAsync("foo", hw, func(lguid string, err error) {
if err != nil {
b.Fatalf("Got an error from ack handler, %v", err)
}
pch <- true
})
} else {
sc.PublishAsync("foo", hw, nil)
}
}
// Wait for published to finish
if err := WaitTime(pch, 10*time.Second); err != nil {
b.Fatalf("Error waiting for publish to finish\n")
}
ch := make(chan bool)
received := int32(0)
b.StartTimer()
b.ReportAllocs()
sc.Subscribe("foo", func(m *Msg) {
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
ch <- true
}
}, DeliverAllAvailable())
err := WaitTime(ch, 10*time.Second)
nr := atomic.LoadInt32(&received)
if err != nil {
b.Fatalf("Timed out waiting for messages, received only %d of %d\n", nr, b.N)
} else if nr != int32(b.N) {
b.Fatalf("Only Received: %d of %d", received, b.N)
}
}
func BenchmarkQueueSubscribe(b *testing.B) {
b.StopTimer()
// Run a NATS Streaming server
s := RunServer(clusterName)
defer s.Shutdown()
sc := NewDefaultConnection(b)
defer sc.Close()
hw := []byte("Hello World")
pch := make(chan bool)
// Queue up all the messages. Keep this outside of the timing.
for i := 0; i < b.N; i++ {
if i == b.N-1 {
// last one
sc.PublishAsync("foo", hw, func(lguid string, err error) {
if err != nil {
b.Fatalf("Got an error from ack handler, %v", err)
}
pch <- true
})
} else {
sc.PublishAsync("foo", hw, nil)
}
}
// Wait for published to finish
if err := WaitTime(pch, 10*time.Second); err != nil {
b.Fatalf("Error waiting for publish to finish\n")
}
ch := make(chan bool)
received := int32(0)
b.StartTimer()
b.ReportAllocs()
mcb := func(m *Msg) {
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
ch <- true
}
}
sc.QueueSubscribe("foo", "bar", mcb, DeliverAllAvailable())
sc.QueueSubscribe("foo", "bar", mcb, DeliverAllAvailable())
sc.QueueSubscribe("foo", "bar", mcb, DeliverAllAvailable())
sc.QueueSubscribe("foo", "bar", mcb, DeliverAllAvailable())
err := WaitTime(ch, 20*time.Second)
nr := atomic.LoadInt32(&received)
if err != nil {
b.Fatalf("Timed out waiting for messages, received only %d of %d\n", nr, b.N)
} else if nr != int32(b.N) {
b.Fatalf("Only Received: %d of %d", received, b.N)
}
}
func BenchmarkPublishSubscribe(b *testing.B) {
b.StopTimer()
// Run a NATS Streaming server
s := RunServer(clusterName)
defer s.Shutdown()
sc := NewDefaultConnection(b)
defer sc.Close()
hw := []byte("Hello World")
ch := make(chan bool)
received := int32(0)
// Subscribe callback, counts msgs received.
_, err := sc.Subscribe("foo", func(m *Msg) {
if nr := atomic.AddInt32(&received, 1); nr >= int32(b.N) {
ch <- true
}
}, DeliverAllAvailable())
if err != nil {
b.Fatalf("Error subscribing, %v", err)
}
b.StartTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_, err := sc.PublishAsync("foo", hw, func(guid string, err error) {
if err != nil {
b.Fatalf("Received an error in publish ack callback: %v\n", err)
}
})
if err != nil {
b.Fatalf("Error publishing %v\n", err)
}
}
err = WaitTime(ch, 30*time.Second)
nr := atomic.LoadInt32(&received)
if err != nil {
b.Fatalf("Timed out waiting for messages, received only %d of %d\n", nr, b.N)
} else if nr != int32(b.N) {
b.Fatalf("Only Received: %d of %d", received, b.N)
}
}
func BenchmarkTimeNow(b *testing.B) {
for i := 0; i < b.N; i++ {
now := time.Now()
now.Add(10 * time.Nanosecond)
}
}