Esempio n. 1
0
func activate(st *store.Store, self string, c *doozer.Client) int64 {
	w := store.NewWatch(st, calGlob)

	for _, base := range store.Getdir(st, calDir) {
		p := calDir + "/" + base
		v, rev := st.Get(p)
		if rev != store.Dir && v[0] == "" {
			seqn, err := c.Set(p, rev, []byte(self))
			if err != nil {
				log.Println(err)
				continue
			}

			w.Stop()
			return seqn
		}
	}

	for ev := range w.C {
		// TODO ev.IsEmpty()
		if ev.IsSet() && ev.Body == "" {
			seqn, err := c.Set(ev.Path, ev.Rev, []byte(self))
			if err != nil {
				log.Println(err)
				continue
			}
			w.Stop()
			return seqn
		}
	}

	return 0
}
Esempio n. 2
0
File: server.go Progetto: 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
			}
		}
	}()
}
Esempio n. 3
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)
	}()
}
Esempio n. 4
0
File: web.go Progetto: 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)
}