예제 #1
0
파일: web.go 프로젝트: soundcloud/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
	}

	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.Seqn
		}
		close(wevs)
	}()

	websocket.Handler(func(ws *websocket.Conn) {
		send(ws, path, wevs)
		ws.Close()
	}).ServeHTTP(w, r)
}
예제 #2
0
파일: txn.go 프로젝트: soundcloud/doozerd
func (t *txn) walk() {
	trace := t.instrumentVerb()

	if !t.c.raccess {
		t.respondOsError(syscall.EACCES)
		trace("eacces")
		return
	}

	if t.req.Path == nil || t.req.Offset == nil {
		t.respondErrCode(Response_MISSING_ARG)
		trace("emissingarg")
		return
	}

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

	offset := *t.req.Offset
	if offset < 0 {
		t.respondErrCode(Response_RANGE)
		trace("erange")
		return
	}

	go func() {
		g, err := t.getter()
		if err != nil {
			t.respondOsError(err)
			trace("eunknown")
			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()
				trace("success")
				return true
			}
			offset--
			return false
		}
		if !store.Walk(g, glob, f) {
			t.respondErrCode(Response_RANGE)
			trace("erange")
		}
	}()
}
예제 #3
0
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
	})
}
예제 #4
0
파일: txn.go 프로젝트: soundcloud/doozerd
func (t *txn) wait() {
	trace := t.instrumentVerb()

	if !t.c.raccess {
		t.respondOsError(syscall.EACCES)
		trace("eacces")
		return
	}

	if t.req.Path == nil || t.req.Rev == nil {
		t.respondErrCode(Response_MISSING_ARG)
		trace("emissingarg")
		return
	}

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

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

	go func() {
		var ev store.Event

		select {
		case ev = <-ch:
		case <-t.c.closed:
			t.c.st.Cancel(ch)
			return
		}

		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()
		trace("success")
	}()
}