예제 #1
0
파일: bench_test.go 프로젝트: vaguer/doozer
func Benchmark5DoozerConClientSet(b *testing.B) {
	b.StopTimer()
	l := mustListen()
	defer l.Close()
	a := l.Addr().String()
	u := mustListenPacket(a)
	defer u.Close()

	l1 := mustListen()
	defer l1.Close()
	u1 := mustListenPacket(l1.Addr().String())
	defer u1.Close()
	l2 := mustListen()
	defer l2.Close()
	u2 := mustListenPacket(l2.Addr().String())
	defer u2.Close()
	l3 := mustListen()
	defer l3.Close()
	u3 := mustListenPacket(l3.Addr().String())
	defer u3.Close()
	l4 := mustListen()
	defer l4.Close()
	u4 := mustListenPacket(l4.Addr().String())
	defer u4.Close()

	go Main("a", "", u, l, nil, 1e9, 1e8, 3e9)
	go Main("a", a, u1, l1, nil, 1e9, 1e8, 3e9)
	go Main("a", a, u2, l2, nil, 1e9, 1e8, 3e9)
	go Main("a", a, u3, l3, nil, 1e9, 1e8, 3e9)
	go Main("a", a, u4, l4, nil, 1e9, 1e8, 3e9)

	cl := client.New("foo", l.Addr().String())
	cl.Set("/ctl/cal/1", store.Missing, nil)
	cl.Set("/ctl/cal/2", store.Missing, nil)
	cl.Set("/ctl/cal/3", store.Missing, nil)
	cl.Set("/ctl/cal/4", store.Missing, nil)

	cls := []*client.Client{
		cl,
		client.New("foo", l1.Addr().String()),
		client.New("foo", l2.Addr().String()),
		client.New("foo", l3.Addr().String()),
		client.New("foo", l4.Addr().String()),
	}

	c := make(chan bool, b.N)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		i := i
		go func() {
			cls[i%len(cls)].Set("/test", store.Clobber, nil)
			c <- true
		}()
	}
	for i := 0; i < b.N; i++ {
		<-c
	}
}
예제 #2
0
파일: nop.go 프로젝트: kr/doozer
func nop() {
	c := client.New("<test>", *addr)

	err := c.Nop()
	if err != nil {
		bail(err)
	}
}
예제 #3
0
파일: get.go 프로젝트: vaguer/doozer
func get(path string) {
	c := client.New("<test>", *addr)

	body, _, err := c.Get(path, nil)
	if err != nil {
		bail(err)
	}

	os.Stdout.Write(body)
}
예제 #4
0
파일: rev.go 프로젝트: kr/doozer
func rev() {
	c := client.New("<test>", *addr)

	rev, err := c.Rev()
	if err != nil {
		bail(err)
	}

	fmt.Println(rev)
}
예제 #5
0
파일: get.go 프로젝트: kr/doozer
func get(path string) {
	c := client.New("<test>", *addr)

	body, rev, err := c.Get(path, nil)
	if err != nil {
		bail(err)
	}

	fmt.Println(rev, len(body))
	os.Stdout.Write(body)
	fmt.Println()
}
예제 #6
0
파일: set.go 프로젝트: kr/doozer
func set(path, rev string) {
	oldRev := mustAtoi64(rev)

	c := client.New("<test>", *addr)

	body, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		bail(err)
	}

	newRev, err := c.Set(path, oldRev, body)
	if err != nil {
		bail(err)
	}

	fmt.Println(newRev)
}
예제 #7
0
파일: bench_test.go 프로젝트: vaguer/doozer
func Benchmark1DoozerClientSet(b *testing.B) {
	b.StopTimer()
	l := mustListen()
	defer l.Close()
	a := l.Addr().String()
	u := mustListenPacket(a)
	defer u.Close()

	go Main("a", "", u, l, nil, 1e9, 2e9, 3e9)

	cl := client.New("foo", l.Addr().String())

	b.StartTimer()
	for i := 0; i < b.N; i++ {
		cl.Set("/test", store.Clobber, nil)
	}
}
예제 #8
0
파일: stat.go 프로젝트: vaguer/doozer
func stat(path string) {
	c := client.New("<test>", *addr)

	len, rev, err := c.Stat(path, nil)
	if err != nil {
		bail(err)
	}

	switch rev {
	case 0:
		fmt.Fprintln(os.Stderr, "No such file or directory:", path)
		os.Exit(proto.Response_NOENT)
	case -2:
		fmt.Println("d", len)
	default:
		fmt.Println(rev, len)
	}
}
예제 #9
0
파일: walk.go 프로젝트: kr/doozer
func walk(glob string) {
	c := client.New("<test>", *addr)

	w, err := c.Walk(glob, nil, nil, nil)
	if err != nil {
		bail(err)
	}

	for ev := range w.C {
		if ev.Err != nil {
			fmt.Fprintln(os.Stderr, ev.Err)
		}

		fmt.Println(ev.Path, ev.Rev, len(ev.Body))
		os.Stdout.Write(ev.Body)
		fmt.Println()
	}
}
예제 #10
0
파일: bench_test.go 프로젝트: vaguer/doozer
func Benchmark5DoozerClientSet(b *testing.B) {
	b.StopTimer()
	l := mustListen()
	defer l.Close()
	a := l.Addr().String()
	u := mustListenPacket(a)
	defer u.Close()

	l1 := mustListen()
	defer l1.Close()
	u1 := mustListenPacket(l1.Addr().String())
	defer u1.Close()
	l2 := mustListen()
	defer l2.Close()
	u2 := mustListenPacket(l2.Addr().String())
	defer u2.Close()
	l3 := mustListen()
	defer l3.Close()
	u3 := mustListenPacket(l3.Addr().String())
	defer u3.Close()
	l4 := mustListen()
	defer l4.Close()
	u4 := mustListenPacket(l4.Addr().String())
	defer u4.Close()

	go Main("a", "", u, l, nil, 1e9, 1e8, 3e9)
	go Main("a", a, u1, l1, nil, 1e9, 1e8, 3e9)
	go Main("a", a, u2, l2, nil, 1e9, 1e8, 3e9)
	go Main("a", a, u3, l3, nil, 1e9, 1e8, 3e9)
	go Main("a", a, u4, l4, nil, 1e9, 1e8, 3e9)

	cl := client.New("foo", l.Addr().String())
	cl.Set("/ctl/cal/1", store.Missing, nil)
	cl.Set("/ctl/cal/2", store.Missing, nil)
	cl.Set("/ctl/cal/3", store.Missing, nil)
	cl.Set("/ctl/cal/4", store.Missing, nil)

	b.StartTimer()
	for i := 0; i < b.N; i++ {
		cl.Set("/test", store.Clobber, nil)
	}
}
예제 #11
0
파일: bench_test.go 프로젝트: vaguer/doozer
func Benchmark1DoozerConClientSet(b *testing.B) {
	b.StopTimer()
	l := mustListen()
	defer l.Close()
	a := l.Addr().String()
	u := mustListenPacket(a)
	defer u.Close()

	go Main("a", "", u, l, nil, 1e9, 2e9, 3e9)

	cl := client.New("foo", l.Addr().String())

	c := make(chan bool, b.N)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		go func() {
			cl.Set("/test", store.Clobber, nil)
			c <- true
		}()
	}
	for i := 0; i < b.N; i++ {
		<-c
	}
}
예제 #12
0
파일: doozer.go 프로젝트: vaguer/doozer
func Main(clusterName, attachAddr string, udpConn net.PacketConn, listener, webListener net.Listener, pulseInterval, fillDelay, kickTimeout int64) {
	listenAddr := listener.Addr().String()

	var activateSeqn int64
	useSelf := make(chan bool, 1)

	self := randId()
	st := store.New()
	pr := &proposer{
		seqns: make(chan int64, alpha),
		props: make(chan *consensus.Prop),
		st:    st,
	}

	calSrv := func() {
		go gc.Pulse(self, st.Seqns, pr, pulseInterval)
		go gc.Clean(st, 360000, time.Tick(1e9))
	}

	if attachAddr == "" { // we are the only node in a new cluster
		set(st, "/ctl/node/"+self+"/addr", listenAddr, store.Missing)
		set(st, "/ctl/node/"+self+"/hostname", os.Getenv("HOSTNAME"), store.Missing)
		set(st, "/ctl/node/"+self+"/version", Version, store.Missing)
		set(st, "/ctl/cal/0", self, store.Missing)
		calSrv()
		close(useSelf)
	} else {
		cl := client.New("local", attachAddr) // TODO use real cluster name
		setC(cl, "/ctl/node/"+self+"/addr", listenAddr, store.Clobber)
		setC(cl, "/ctl/node/"+self+"/hostname", os.Getenv("HOSTNAME"), store.Clobber)
		setC(cl, "/ctl/node/"+self+"/version", Version, store.Clobber)

		rev, err := cl.Rev()
		if err != nil {
			panic(err)
		}

		walk, err := cl.Walk("/**", &rev, nil, nil)
		if err != nil {
			panic(err)
		}

		watch, err := cl.Watch("/**", rev+1)
		if err != nil {
			panic(err)
		}

		go follow(st.Ops, watch.C)
		follow(st.Ops, walk.C)
		st.Flush()
		ch, err := st.Wait(rev + 1)
		if err == nil {
			<-ch
		}

		go func() {
			activateSeqn = activate(st, self, cl)
			calSrv()
			advanceUntil(cl, st.Seqns, activateSeqn+alpha)
			err := watch.Cancel()
			if err != nil {
				panic(err)
			}
			close(useSelf)
		}()
	}

	start := <-st.Seqns
	cmw := st.Watch(store.Any)
	in := make(chan consensus.Packet, 50)
	out := make(chan consensus.Packet, 50)

	consensus.NewManager(self, start, alpha, in, out, st.Ops, pr.seqns, pr.props, cmw, fillDelay, st)

	if attachAddr == "" {
		// Skip ahead alpha steps so that the registrar can provide a
		// meaningful cluster.
		for i := start + 1; i < start+alpha+1; i++ {
			st.Ops <- store.Op{i, store.Nop}
		}
	}

	shun := make(chan string, 3) // sufficient for a cluster of 7

	go member.Clean(shun, st, pr)

	sv := &server.Server{listenAddr, st, pr, self, alpha}

	go sv.Serve(listener, useSelf)

	if webListener != nil {
		web.Store = st
		web.ClusterName = clusterName
		go web.Serve(webListener)
	}

	go func() {
		for p := range out {
			addr, err := net.ResolveUDPAddr(p.Addr)
			if err != nil {
				log.Println(err)
				continue
			}
			n, err := udpConn.WriteTo(p.Data, addr)
			if err != nil {
				log.Println(err)
				continue
			}
			if n != len(p.Data) {
				log.Println("packet len too long:", len(p.Data))
				continue
			}
		}
	}()

	lv := liveness{
		timeout: kickTimeout,
		ival:    kickTimeout / 2,
		times:   make(map[string]int64),
		self:    self,
		shun:    shun,
	}
	for {
		t := time.Nanoseconds()

		buf := make([]byte, maxUDPLen)
		n, addr, err := udpConn.ReadFrom(buf)
		if err == os.EINVAL {
			return
		}
		if err != nil {
			log.Println(err)
			continue
		}

		buf = buf[:n]

		// Update liveness time stamp for this addr
		lv.times[addr.String()] = t
		lv.check(t)

		in <- consensus.Packet{addr.String(), buf}
	}
}