Example #1
0
func (fm *FileMgr) setupNatsOptions() {

	if !fm.certs.skipTLS {
		err := fm.certs.certLoad()
		if err != nil {
			panic(err)
		}
	}

	o := []nats.Option{}
	o = append(o, nats.MaxReconnects(-1)) // -1 => keep trying forever
	o = append(o, nats.ReconnectWait(2*time.Second))
	o = append(o, nats.Name("archiver"))

	o = append(o, nats.ErrorHandler(func(c *nats.Conn, s *nats.Subscription, e error) {
		fm.NatsAsyncErrCh <- asyncErr{conn: c, sub: s, err: e}
	}))
	o = append(o, nats.DisconnectHandler(func(conn *nats.Conn) {
		fm.NatsConnDisconCh <- conn
	}))
	o = append(o, nats.ReconnectHandler(func(conn *nats.Conn) {
		fm.NatsConnReconCh <- conn
	}))
	o = append(o, nats.ClosedHandler(func(conn *nats.Conn) {
		fm.NatsConnClosedCh <- conn
	}))

	if !fm.certs.skipTLS {
		o = append(o, nats.Secure(&fm.certs.tlsConfig))
		o = append(o, fm.certs.rootCA)
	}

	fm.opts = o
}
Example #2
0
func TestCallbacksOrder(t *testing.T) {
	authS, authSOpts := RunServerWithConfig("./configs/tls.conf")
	defer authS.Shutdown()

	s := RunDefaultServer()
	defer s.Shutdown()

	firstDisconnect := true
	dtime1 := time.Time{}
	dtime2 := time.Time{}
	rtime := time.Time{}
	atime1 := time.Time{}
	atime2 := time.Time{}
	ctime := time.Time{}

	cbErrors := make(chan error, 20)

	reconnected := make(chan bool)
	closed := make(chan bool)
	asyncErr := make(chan bool, 2)
	recvCh := make(chan bool, 2)
	recvCh1 := make(chan bool)
	recvCh2 := make(chan bool)

	dch := func(nc *nats.Conn) {
		if err := isRunningInAsyncCBDispatcher(); err != nil {
			cbErrors <- err
			return
		}
		time.Sleep(100 * time.Millisecond)
		if firstDisconnect {
			firstDisconnect = false
			dtime1 = time.Now()
		} else {
			dtime2 = time.Now()
		}
	}

	rch := func(nc *nats.Conn) {
		if err := isRunningInAsyncCBDispatcher(); err != nil {
			cbErrors <- err
			reconnected <- true
			return
		}
		time.Sleep(50 * time.Millisecond)
		rtime = time.Now()
		reconnected <- true
	}

	ech := func(nc *nats.Conn, sub *nats.Subscription, err error) {
		if err := isRunningInAsyncCBDispatcher(); err != nil {
			cbErrors <- err
			asyncErr <- true
			return
		}
		if sub.Subject == "foo" {
			time.Sleep(20 * time.Millisecond)
			atime1 = time.Now()
		} else {
			atime2 = time.Now()
		}
		asyncErr <- true
	}

	cch := func(nc *nats.Conn) {
		if err := isRunningInAsyncCBDispatcher(); err != nil {
			cbErrors <- err
			closed <- true
			return
		}
		ctime = time.Now()
		closed <- true
	}

	url := net.JoinHostPort(authSOpts.Host, strconv.Itoa(authSOpts.Port))
	url = "nats://" + url + "," + nats.DefaultURL

	nc, err := nats.Connect(url,
		nats.DisconnectHandler(dch),
		nats.ReconnectHandler(rch),
		nats.ClosedHandler(cch),
		nats.ErrorHandler(ech),
		nats.ReconnectWait(50*time.Millisecond),
		nats.DontRandomize())
	if err != nil {
		t.Fatalf("Unable to connect: %v\n", err)
	}
	defer nc.Close()

	ncp, err := nats.Connect(nats.DefaultURL,
		nats.ReconnectWait(50*time.Millisecond))
	if err != nil {
		t.Fatalf("Unable to connect: %v\n", err)
	}
	defer ncp.Close()

	// Wait to make sure that if we have closed (incorrectly) the
	// asyncCBDispatcher during the connect process, this is caught here.
	time.Sleep(time.Second)

	s.Shutdown()

	s = RunDefaultServer()
	defer s.Shutdown()

	if err := Wait(reconnected); err != nil {
		t.Fatal("Did not get the reconnected callback")
	}

	var sub1 *nats.Subscription
	var sub2 *nats.Subscription

	recv := func(m *nats.Msg) {
		// Signal that one message is received
		recvCh <- true

		// We will now block
		if m.Subject == "foo" {
			<-recvCh1
		} else {
			<-recvCh2
		}
		m.Sub.Unsubscribe()
	}

	sub1, err = nc.Subscribe("foo", recv)
	if err != nil {
		t.Fatalf("Unable to create subscription: %v\n", err)
	}
	sub1.SetPendingLimits(1, 100000)

	sub2, err = nc.Subscribe("bar", recv)
	if err != nil {
		t.Fatalf("Unable to create subscription: %v\n", err)
	}
	sub2.SetPendingLimits(1, 100000)

	nc.Flush()

	ncp.Publish("foo", []byte("test"))
	ncp.Publish("bar", []byte("test"))
	ncp.Flush()

	// Wait notification that message were received
	err = Wait(recvCh)
	if err == nil {
		err = Wait(recvCh)
	}
	if err != nil {
		t.Fatal("Did not receive message")
	}

	for i := 0; i < 2; i++ {
		ncp.Publish("foo", []byte("test"))
		ncp.Publish("bar", []byte("test"))
	}
	ncp.Flush()

	if err := Wait(asyncErr); err != nil {
		t.Fatal("Did not get the async callback")
	}
	if err := Wait(asyncErr); err != nil {
		t.Fatal("Did not get the async callback")
	}

	close(recvCh1)
	close(recvCh2)

	nc.Close()

	if err := Wait(closed); err != nil {
		t.Fatal("Did not get the close callback")
	}

	if len(cbErrors) > 0 {
		t.Fatalf("%v", <-cbErrors)
	}

	if (dtime1 == time.Time{}) || (dtime2 == time.Time{}) || (rtime == time.Time{}) || (atime1 == time.Time{}) || (atime2 == time.Time{}) || (ctime == time.Time{}) {
		t.Fatalf("Some callbacks did not fire:\n%v\n%v\n%v\n%v\n%v\n%v", dtime1, rtime, atime1, atime2, dtime2, ctime)
	}

	if rtime.Before(dtime1) || dtime2.Before(rtime) || atime2.Before(atime1) || ctime.Before(atime2) {
		t.Fatalf("Wrong callback order:\n%v\n%v\n%v\n%v\n%v\n%v", dtime1, rtime, atime1, atime2, dtime2, ctime)
	}
}
Example #3
0
func Test003ArchiverAcknowledgesStorage(t *testing.T) {

	cv.Convey("given a running gnatsd, the archiver should store messages to disk and acknowledge their storage on the 'servicename.storage-ack.(hostname)' subject.", t, func() {

		user := "******"
		pw := "password"
		host := "127.0.0.1"
		port := 4444
		serverList := fmt.Sprintf("nats://%v:%v@%v:%v", user, pw, host, port)

		// start yourself an embedded gnatsd server
		opts := server.Options{
			Host:     host,
			Port:     port,
			Username: user,
			Password: pw,
			Trace:    true,
			Debug:    true,
			//NoLog:  true,
			//NoSigs: true,
		}
		gnats := gnatsd.RunServer(&opts)
		gnats.SetLogger(&Logger{}, true, true)

		//logger := log.New(os.Stderr, "gnatsd: ", log.LUTC|log.Ldate|log.Ltime|log.Lmicroseconds|log.Llongfile)
		defer func() {
			p("calling gnats.Shutdown()")
			gnats.Shutdown() // when done
		}()
		addr := fmt.Sprintf("%v:%v", host, port)
		if !PortIsBound(addr) {
			panic("port not bound " + addr)
		}

		// start client
		asyncHandler := nats.ErrorHandler(func(c *nats.Conn, s *nats.Subscription, e error) {
			fmt.Printf("\n *** async error handler sees error: '%s'\n", e)
			panic(e)
		})
		p("about to connect with client")
		nc, err := nats.Connect(serverList, asyncHandler)
		panicOn(err)
		defer nc.Close()

		// prep data
		p("prepping data")
		streamName := "test"
		data1 := []byte("data1")

		tm1, err := time.Parse(time.RFC3339, "2016-01-01T00:00:00Z")
		panicOn(err)

		frame1, err := ts.NewFrame(tm1, ts.EvUtf8, 0, 0, data1)
		panicOn(err)
		framed, err := frame1.Marshal(nil)
		panicOn(err)

		// subscribe to reply in advance of publishing archive request
		gotAck := make(chan *nats.Msg)
		nc.Subscribe(ServiceName+".storage-ack.>", func(msgNats *nats.Msg) {
			p(ServiceName+".storage-ack received msg: '%#v'", msgNats)
			select {
			case <-gotAck:
				// already closed; don't do it again
				p(ServiceName + ".storage-ack already closed, skipping this time")
			default:
				p(ServiceName + ".storage-ack closing gotAck")
				close(gotAck)
			}
		})

		// start an archiver to catch our request
		tmp, err := ioutil.TempDir("", "test-archiver-filemgr")
		panicOn(err)
		defer os.RemoveAll(tmp)
		fm := NewFileMgr(&ArchiverConfig{WriteDir: tmp,
			ServerList: serverList})
		go func() {
			err := fm.Run()
			panicOn(err)
		}()
		<-fm.Ready
		p("archiver_test: fm.Ready received")
		defer fm.Stop()

		// make the achiving request: write data to server
		subj := ServiceName + ".archive." + streamName

		err = nc.Publish(subj, framed)
		if err != nil {
			panic(fmt.Errorf("Got an error on nc.Publish(): %+v\n", err))
		}
		nc.Flush()
		p("Published to subject '%s' %v bytes", subj, len(framed))
		reply, err := nc.Request(subj, framed, 1000*time.Millisecond)
		if err != nil {
			p("\n ----------->>>>>>> Request got err back: '%s'\n", err)
			panic(fmt.Errorf("Error in Request: %v\n", err))
		}
		p("003ArchiverAck test sent request, got reply: '%#v' with Data '%s'", reply, string(reply.Data))
		cv.So(strings.HasPrefix(reply.Subject, "_INBOX."), cv.ShouldBeTrue)
		// verify reply or panic after timeout
		timeout := 2 * time.Second
		select {
		case <-gotAck:
			// cool
			p("successfully got ack!")
		case <-time.After(timeout):
			panic(fmt.Errorf("timeout after %v waiting for reply", timeout))
		}
	})
}