Ejemplo n.º 1
0
func evServer(w http.ResponseWriter, r *http.Request) {
	wevs := make(chan store.Event)
	path := r.URL.Path[len("/$events"):]

	glob, err := store.CompileGlob(path + "**")
	if err != nil {
		w.WriteHeader(400)
		return
	}

	rev, _ := Store.Snap()

	go func() {
		walk(path, Store, wevs)
		for {
			ch, err := Store.Wait(glob, rev+1)
			if err != nil {
				break
			}
			ev, ok := <-ch
			if !ok {
				break
			}
			wevs <- ev
			rev = ev.Rev
		}
		close(wevs)
	}()

	websocket.Handler(func(ws *websocket.Conn) {
		send(ws, path, wevs)
		ws.Close()
	}).ServeHTTP(w, r)
}
Ejemplo n.º 2
0
Archivo: server.go Proyecto: kr/doozerd
func (c *conn) walk(t *T, tx txn) {
	pat := pb.GetString(t.Path)
	glob, err := store.CompileGlob(pat)
	if err != nil {
		c.respond(t, Valid|Done, nil, errResponse(err))
		return
	}

	offset := pb.GetInt32(t.Offset)
	if offset < 0 {
		c.respond(t, Valid|Done, nil, erange)
		return
	}

	if g := c.getterFor(t); g != nil {
		var r R
		f := func(path, body string, rev int64) (stop bool) {
			if offset == 0 {
				r.Path = &path
				r.Value = []byte(body)
				r.Rev = &rev
				return true
			}
			offset--
			return false
		}
		if store.Walk(g, glob, f) {
			c.respond(t, Set|Valid|Done, nil, &r)
		} else {
			c.respond(t, Valid|Done, nil, erange)
		}
	}
}
Ejemplo n.º 3
0
Archivo: server.go Proyecto: kr/doozerd
func (c *conn) watch(t *T, tx txn) {
	pat := pb.GetString(t.Path)
	glob, err := store.CompileGlob(pat)
	if err != nil {
		c.respond(t, Valid|Done, nil, errResponse(err))
		return
	}

	var w *store.Watch
	rev := pb.GetInt64(t.Rev)
	if rev == 0 {
		w, err = store.NewWatch(c.s.St, glob), nil
	} else {
		w, err = store.NewWatchFrom(c.s.St, glob, rev)
	}

	switch err {
	case nil:
		// nothing
	case store.ErrTooLate:
		c.respond(t, Valid|Done, nil, tooLate)
	default:
		c.respond(t, Valid|Done, nil, errResponse(err))
	}

	go func() {
		defer w.Stop()

		// TODO buffer (and possibly discard) events
		for {
			select {
			case ev := <-w.C:
				if closed(w.C) {
					return
				}

				r := R{
					Path:  &ev.Path,
					Value: []byte(ev.Body),
					Rev:   &ev.Seqn,
				}

				var flag int32
				switch {
				case ev.IsSet():
					flag = Set
				case ev.IsDel():
					flag = Del
				}

				c.respond(t, Valid|flag, tx.cancel, &r)

			case <-tx.cancel:
				c.closeTxn(*t.Tag)
				return
			}
		}
	}()
}
Ejemplo n.º 4
0
Archivo: member.go Proyecto: kr/doozer
func removeInfo(p consensus.Proposer, g store.Getter, name string) {
	glob, err := store.CompileGlob("/ctl/node/" + name + "/**")
	if err != nil {
		log.Println(err)
		return
	}
	store.Walk(g, glob, func(path, _ string, rev int64) bool {
		consensus.Del(p, path, rev)
		return false
	})
}
Ejemplo n.º 5
0
func (t *txn) walk() {
	if t.c.access == false {
		t.respondOsError(os.EACCES)
		return
	}

	if t.req.Path == nil || t.req.Offset == nil {
		t.respondErrCode(response_MISSING_ARG)
		return
	}

	glob, err := store.CompileGlob(*t.req.Path)
	if err != nil {
		t.respondOsError(err)
		return
	}

	offset := *t.req.Offset
	if offset < 0 {
		t.respondErrCode(response_RANGE)
		return
	}

	go func() {
		g, err := t.getter()
		if err != nil {
			t.respondOsError(err)
			return
		}

		f := func(path, body string, rev int64) (stop bool) {
			if offset == 0 {
				t.resp.Path = &path
				t.resp.Value = []byte(body)
				t.resp.Rev = &rev
				t.resp.Flags = proto.Int32(set)
				t.respond()
				return true
			}
			offset--
			return false
		}
		if !store.Walk(g, glob, f) {
			t.respondErrCode(response_RANGE)
		}
	}()
}
Ejemplo n.º 6
0
func (c *conn) walk(t *T, tx txn) {
	pat := pb.GetString(t.Path)
	glob, err := store.CompileGlob(pat)
	if err != nil {
		c.respond(t, Valid|Done, nil, errResponse(err))
		return
	}

	offset := pb.GetInt32(t.Offset)

	var limit int32 = math.MaxInt32
	if t.Limit != nil {
		limit = pb.GetInt32(t.Limit)
	}

	if g := c.getterFor(t); g != nil {
		go func() {
			f := func(path, body string, rev int64) (stop bool) {
				select {
				case <-tx.cancel:
					c.closeTxn(*t.Tag)
					return true
				default:
				}

				if offset <= 0 && limit > 0 {
					var r R
					r.Path = &path
					r.Value = []byte(body)
					r.Rev = &rev
					c.respond(t, Valid|Set, tx.cancel, &r)

					limit--
				}

				offset--
				return false
			}

			stopped := store.Walk(g, glob, f)

			if !stopped {
				c.respond(t, Done, nil, &R{})
			}
		}()
	}
}
Ejemplo n.º 7
0
func (c *conn) wait(t *T, tx txn) {
	pat := pb.GetString(t.Path)
	glob, err := store.CompileGlob(pat)
	if err != nil {
		c.respond(t, Valid|Done, nil, errResponse(err))
		return
	}

	var w *store.Watch
	rev := pb.GetInt64(t.Rev)
	if rev == 0 {
		w, err = store.NewWatch(c.s.St, glob), nil
	} else {
		w, err = store.NewWatchFrom(c.s.St, glob, rev)
	}

	switch err {
	case nil:
		// nothing
	case store.ErrTooLate:
		c.respond(t, Valid|Done, nil, tooLate)
	default:
		c.respond(t, Valid|Done, nil, errResponse(err))
	}

	go func() {
		defer w.Stop()
		ev := <-w.C
		r := R{
			Path:  &ev.Path,
			Value: []byte(ev.Body),
			Rev:   &ev.Seqn,
		}

		var flag int32
		switch {
		case ev.IsSet():
			flag = Set
		case ev.IsDel():
			flag = Del
		}

		c.respond(t, Valid|flag, nil, &r)
	}()
}
Ejemplo n.º 8
0
func (t *txn) wait() {
	if t.c.access == false {
		t.respondOsError(os.EACCES)
		return
	}

	if t.req.Path == nil || t.req.Rev == nil {
		t.respondErrCode(response_MISSING_ARG)
		return
	}

	glob, err := store.CompileGlob(*t.req.Path)
	if err != nil {
		t.respondOsError(err)
		return
	}

	ch, err := t.c.st.Wait(glob, *t.req.Rev)
	if err != nil {
		t.respondOsError(err)
		return
	}

	go func() {
		ev := <-ch
		t.resp.Path = &ev.Path
		t.resp.Value = []byte(ev.Body)
		t.resp.Rev = &ev.Seqn
		switch {
		case ev.IsSet():
			t.resp.Flags = proto.Int32(set)
		case ev.IsDel():
			t.resp.Flags = proto.Int32(del)
		default:
			t.resp.Flags = proto.Int32(0)
		}
		t.respond()
	}()
}
Ejemplo n.º 9
0
Archivo: web.go Proyecto: kr/doozerd
func evServer(w http.ResponseWriter, r *http.Request) {
	wevs := make(chan store.Event)
	path := r.URL.Path[len("/$events"):]

	glob, err := store.CompileGlob(path + "**")
	if err != nil {
		w.WriteHeader(400)
		return
	}

	wt := store.NewWatch(Store, glob)

	go func() {
		walk(path, Store, wevs)
		close(wevs)
	}()

	websocket.Handler(func(ws *websocket.Conn) {
		send(ws, path, wevs)
		send(ws, path, wt.C)
		wt.Stop()
		ws.Close()
	}).ServeHTTP(w, r)
}