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 }
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 } } }() }
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) }() }
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) }