Beispiel #1
0
// NewSocket allocates a new Socket.  The Socket is the handle used to
// access the underlying library.
func NewSocket(d Domain, p Protocol) (*Socket, error) {

	var s Socket
	var err error

	s.proto = p
	s.dom = d

	switch p {
	case PUB:
		s.sock, err = pub.NewSocket()
	case SUB:
		s.sock, err = sub.NewSocket()
	case PUSH:
		s.sock, err = push.NewSocket()
	case PULL:
		s.sock, err = pull.NewSocket()
	case REQ:
		s.sock, err = req.NewSocket()
	case REP:
		s.sock, err = rep.NewSocket()
	case SURVEYOR:
		s.sock, err = surveyor.NewSocket()
	case RESPONDENT:
		s.sock, err = respondent.NewSocket()
	case PAIR:
		s.sock, err = pair.NewSocket()
	case BUS:
		s.sock, err = bus.NewSocket()
	default:
		err = mangos.ErrBadProto
	}

	if err != nil {
		return nil, err
	}

	switch d {
	case AF_SP:
	case AF_SP_RAW:
		err = s.sock.SetOption(mangos.OptionRaw, true)
	default:
		err = errBadDomain
	}
	if err != nil {
		s.sock.Close()
		return nil, err
	}

	// Compat mode sockets should timeout on send if we don't have any pipes
	if err = s.sock.SetOption(mangos.OptionWriteQLen, 0); err != nil {
		s.sock.Close()
		return nil, err
	}

	s.rto = -1
	s.sto = -1
	all.AddTransports(s.sock)
	return &s, nil
}
Beispiel #2
0
// ThroughputServer is the server side -- very much equivalent to local_thr in
// nanomsg/perf.  It does the measurement by counting packets received.
func ThroughputServer(addr string, msgSize int, count int) {
	s, err := pair.NewSocket()
	if err != nil {
		log.Fatalf("Failed to make new pair socket: %v", err)
	}
	defer s.Close()

	all.AddTransports(s)
	l, err := s.NewListener(addr, nil)
	if err != nil {
		log.Fatalf("Failed to make new listener: %v", err)
	}

	// Disable TCP no delay, please! - only valid for TCP
	l.SetOption(mangos.OptionNoDelay, false)

	// Make sure we linger a bit on close...
	err = s.SetOption(mangos.OptionLinger, time.Second)
	if err != nil {
		log.Fatalf("Failed set Linger: %v", err)
	}

	err = l.Listen()
	if err != nil {
		log.Fatalf("Failed to listen: %v", err)
	}

	msg, err := s.RecvMsg()
	msg.Free()

	start := time.Now()

	for i := 0; i != count; i++ {
		msg, err := s.RecvMsg()
		if err != nil {
			log.Fatalf("Failed to recv: %v", err)
		}
		if len(msg.Body) != msgSize {
			log.Fatalf("Received wrong message size: %d != %d", len(msg.Body), msgSize)
		}
		// return to cache to avoid GC
		msg.Free()
	}

	finish := time.Now()

	delta := finish.Sub(start)
	deltasec := float64(delta) / float64(time.Second)
	msgpersec := float64(count) / deltasec
	mbps := (float64((count)*8*msgSize) / deltasec) / 1000000.0
	fmt.Printf("message size: %d [B]\n", msgSize)
	fmt.Printf("message count: %d\n", count)
	fmt.Printf("throughput: %d [msg/s]\n", uint64(msgpersec))
	fmt.Printf("throughput: %.3f [Mb/s]\n", mbps)
}
Beispiel #3
0
func setSocket(f func() (mangos.Socket, error)) error {
	var err error
	if sock != nil {
		return errors.New("protocol already selected")
	}
	sock, err = f()
	if err != nil {
		return err
	}
	all.AddTransports(sock)
	return nil
}
Beispiel #4
0
// LatencyClient is the client side of the latency test.  It measures round
// trip times, and is the equivalent to nanomsg/perf/remote_lat.
func LatencyClient(addr string, msgSize int, roundTrips int) {
	s, err := pair.NewSocket()
	if err != nil {
		log.Fatalf("Failed to make new pair socket: %v", err)
	}
	defer s.Close()

	all.AddTransports(s)
	d, err := s.NewDialer(addr, nil)
	if err != nil {
		log.Fatalf("Failed to make new dialer: %v", err)
	}

	// TCP no delay, please!
	d.SetOption(mangos.OptionNoDelay, true)

	// Make sure we linger a bit on close...
	err = s.SetOption(mangos.OptionLinger, time.Second)
	if err != nil {
		log.Fatalf("Failed set Linger: %v", err)
	}

	err = d.Dial()
	if err != nil {
		log.Fatalf("Failed to dial: %v", err)
	}

	// 100 milliseconds to give TCP a chance to establish
	//time.Sleep(time.Millisecond * 100)
	msg := mangos.NewMessage(msgSize)
	msg.Body = msg.Body[0:msgSize]

	start := time.Now()
	for i := 0; i < roundTrips; i++ {
		if err = s.SendMsg(msg); err != nil {
			log.Fatalf("Failed SendMsg: %v", err)
		}
		if msg, err = s.RecvMsg(); err != nil {
			log.Fatalf("Failed RecvMsg: %v", err)
		}
	}
	finish := time.Now()
	msg.Free()

	total := (finish.Sub(start)) / time.Microsecond
	lat := float64(total) / float64(roundTrips*2)
	fmt.Printf("message size: %d [B]\n", msgSize)
	fmt.Printf("round trip count: %d\n", roundTrips)
	fmt.Printf("average latency: %.3f [us]\n", lat)
}
Beispiel #5
0
func (c *T) Init(t *testing.T, addr string) bool {
	time.Sleep(100 * time.Millisecond)
	// Initial defaults
	c.Lock()
	defer c.Unlock()
	c.t = t
	c.addr = addr
	c.numrx = 0 // Reset
	c.numtx = 0 // Reset
	c.sdoneq = make(chan struct{})
	c.rdoneq = make(chan struct{})
	c.readyq = make(chan struct{})
	c.timeout = time.Second * 3
	c.txdelay = time.Duration(time.Now().UnixNano()) % time.Millisecond

	all.AddTransports(c.Sock)
	return true
}
Beispiel #6
0
// ThroughputClient is the client side of the latency test.  It simply sends
// the requested number of packets of given size to the server.  It corresponds
// to remote_thr.
func ThroughputClient(addr string, msgSize int, count int) {
	s, err := pair.NewSocket()
	if err != nil {
		log.Fatalf("Failed to make new pair socket: %v", err)
	}
	defer s.Close()

	all.AddTransports(s)
	d, err := s.NewDialer(addr, nil)
	if err != nil {
		log.Fatalf("Failed to make new dialer: %v", err)
	}

	// Disable TCP no delay, please!
	d.SetOption(mangos.OptionNoDelay, false)

	// Make sure we linger a bit on close...
	err = s.SetOption(mangos.OptionLinger, time.Second)
	if err != nil {
		log.Fatalf("Failed set Linger: %v", err)
	}

	err = d.Dial()
	if err != nil {
		log.Fatalf("Failed to dial: %v", err)
	}

	// 100 milliseconds to give TCP a chance to establish
	time.Sleep(time.Millisecond * 100)

	body := make([]byte, msgSize)
	for i := 0; i < msgSize; i++ {
		body[i] = 111
	}

	// send the start message
	s.Send([]byte{})

	for i := 0; i < count; i++ {
		if err = s.Send(body); err != nil {
			log.Fatalf("Failed SendMsg: %v", err)
		}
	}
}
Beispiel #7
0
// LatencyServer is the server side -- very much equivalent to local_lat in
// nanomsg/perf.  It does no measurement at all, just sends packets on the wire.
func LatencyServer(addr string, msgSize int, roundTrips int) {
	s, err := pair.NewSocket()
	if err != nil {
		log.Fatalf("Failed to make new pair socket: %v", err)
	}
	defer s.Close()

	all.AddTransports(s)
	l, err := s.NewListener(addr, nil)
	if err != nil {
		log.Fatalf("Failed to make new listener: %v", err)
	}

	// TCP no delay, please!
	l.SetOption(mangos.OptionNoDelay, true)

	// Make sure we linger a bit on close...
	err = s.SetOption(mangos.OptionLinger, time.Second)
	if err != nil {
		log.Fatalf("Failed set Linger: %v", err)
	}

	err = l.Listen()
	if err != nil {
		log.Fatalf("Failed to listen: %v", err)
	}
	for i := 0; i != roundTrips; i++ {
		msg, err := s.RecvMsg()
		if err != nil {
			log.Fatalf("Failed to recv: %v", err)
		}
		if len(msg.Body) != msgSize {
			log.Fatalf("Received wrong message size: %d != %d", len(msg.Body), msgSize)
		}
		if err = s.SendMsg(msg); err != nil {
			log.Fatalf("Failed to send: %v", err)
		}
	}
}
Beispiel #8
0
func benchmarkReq(t *testing.B, url string, size int) {

	if strings.HasPrefix(url, "ipc://") && runtime.GOOS == "windows" {
		t.Skip("IPC not supported on Windows")
		return
	}

	srvopts := make(map[string]interface{})
	cliopts := make(map[string]interface{})

	if strings.HasPrefix(url, "wss://") || strings.HasPrefix(url, "tls+tcp://") {
		srvopts[mangos.OptionTLSConfig] = srvCfg
		cliopts[mangos.OptionTLSConfig] = cliCfg
	}
	srvrdy := make(chan struct{})
	srvsock, err := rep.NewSocket()
	if err != nil || srvsock == nil {
		t.Errorf("Failed creating server socket: %v", err)
		return
	}
	defer srvsock.Close()

	all.AddTransports(srvsock)

	clisock, err := req.NewSocket()
	if err != nil || clisock == nil {
		t.Errorf("Failed creating client socket: %v", err)
		return
	}
	defer clisock.Close()
	all.AddTransports(clisock)

	go func() {
		var err error
		var msg *mangos.Message

		if err = srvsock.ListenOptions(url, srvopts); err != nil {
			t.Errorf("Server listen failed: %v", err)
			return
		}

		close(srvrdy)
		// echo server

		for {
			if msg, err = srvsock.RecvMsg(); err != nil {
				return
			}
			if err = srvsock.SendMsg(msg); err != nil {
				t.Errorf("Server send failed: %v", err)
				return
			}
		}

	}()

	if err = clisock.DialOptions(url, cliopts); err != nil {
		t.Errorf("Client dial failed: %v", err)
		return
	}
	<-srvrdy

	time.Sleep(time.Millisecond * 1000)
	t.ResetTimer()
	msg := make([]byte, size)

	for i := 0; i < t.N; i++ {
		if err = clisock.Send(msg); err != nil {
			t.Errorf("Client send failed: %v", err)
			return
		}
		if msg, err = clisock.Recv(); err != nil {
			t.Errorf("Client receive failed: %v", err)
			return
		}
	}
	if size > 128 {
		t.SetBytes(int64(size))
	}
	t.StopTimer()
}
Beispiel #9
0
func benchmarkPair(t *testing.B, url string, size int) {

	if strings.HasPrefix(url, "ipc://") && runtime.GOOS == "windows" {
		t.Skip("IPC not supported on Windows")
		return
	}

	srvopts := make(map[string]interface{})
	cliopts := make(map[string]interface{})

	if strings.HasPrefix(url, "wss://") || strings.HasPrefix(url, "tls+tcp://") {
		srvopts[mangos.OptionTLSConfig] = srvCfg
		cliopts[mangos.OptionTLSConfig] = cliCfg
	}

	finish := make(chan struct{})
	ready := make(chan struct{})
	srvsock, err := pair.NewSocket()
	if err != nil || srvsock == nil {
		t.Errorf("Failed creating server socket: %v", err)
		return
	}
	all.AddTransports(srvsock)
	defer srvsock.Close()

	clisock, err := pair.NewSocket()
	if err != nil || clisock == nil {
		t.Errorf("Failed creating client socket: %v", err)
		return
	}
	all.AddTransports(clisock)
	defer clisock.Close()

	go func() {
		var err error
		var m *mangos.Message

		if err = srvsock.ListenOptions(url, srvopts); err != nil {
			t.Errorf("Server listen failed: %v", err)
			return
		}
		close(ready)
		for i := 0; i < t.N; i++ {
			if m, err = srvsock.RecvMsg(); err != nil {
				t.Errorf("Error receiving %d: %v", i, err)
				return
			}
			m.Free()
		}
		close(finish)

	}()
	<-ready

	if err = clisock.DialOptions(url, cliopts); err != nil {
		t.Errorf("Client dial failed: %v", err)
		return
	}

	time.Sleep(700 * time.Millisecond)
	t.ResetTimer()

	for i := 0; i < t.N; i++ {
		msg := mangos.NewMessage(size)
		if err = clisock.SendMsg(msg); err != nil {
			t.Errorf("Client send failed: %v", err)
			return
		}
	}
	<-finish
	t.StopTimer()
	if size > 128 {
		t.SetBytes(int64(size))
	}
}