feat(server): revision authors, revisions after a seq, online machines
This commit is contained in:
1 parent
91d83f3032
commit
c2e9284a63
6 files changed
+299
-15
No files matched your search
@@ -50,12 +50,14 @@ type Server struct {
|
||||
|
||||
mu sync.Mutex
|
||||
subscribers map[chan protocol.Event]struct{}
|
||||
streams map[int64]int
|
||||
seen map[int64]int64
|
||||
}
|
||||
|
||||
type machineKey struct{}
|
||||
|
||||
func New(store *Store, config Config) http.Handler {
|
||||
s := &Server{config: config, store: store, subscribers: map[chan protocol.Event]struct{}{}}
|
||||
s := &Server{config: config, store: store, subscribers: map[chan protocol.Event]struct{}{}, streams: map[int64]int{}, seen: map[int64]int64{}}
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("GET /i/{code}", s.install)
|
||||
mux.Handle("GET /dl/", http.StripPrefix("/dl/", http.FileServer(http.Dir(config.ClientsDir))))
|
||||
@@ -136,6 +138,7 @@ func (s *Server) auth(next http.HandlerFunc) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
machineID = id
|
||||
s.track(id, 0)
|
||||
}
|
||||
if key := r.PathValue("key"); key != "" && !repoKeyPattern.MatchString(key) {
|
||||
http.Error(w, "bad repository key", http.StatusBadRequest)
|
||||
@@ -206,12 +209,25 @@ func (s *Server) logout(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func (s *Server) track(machineID int64, streams int) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.seen[machineID] = time.Now().UnixMilli()
|
||||
s.streams[machineID] += streams
|
||||
}
|
||||
|
||||
func (s *Server) machines(w http.ResponseWriter, r *http.Request) {
|
||||
machines, err := s.store.Machines(r.Context())
|
||||
if err != nil {
|
||||
writeError(w, err)
|
||||
return
|
||||
}
|
||||
s.mu.Lock()
|
||||
for i, machine := range machines {
|
||||
machines[i].Online = s.streams[machine.ID] > 0
|
||||
machines[i].LastSeen = max(s.seen[machine.ID], machine.LastPush)
|
||||
}
|
||||
s.mu.Unlock()
|
||||
writeJSON(w, http.StatusOK, machines)
|
||||
}
|
||||
|
||||
@@ -287,7 +303,19 @@ func (s *Server) state(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *Server) revisions(w http.ResponseWriter, r *http.Request) {
|
||||
revisions, err := s.store.Revisions(r.Context(), r.PathValue("key"), r.URL.Query().Get("path"))
|
||||
key, query := r.PathValue("key"), r.URL.Query()
|
||||
var revisions []protocol.Revision
|
||||
var err error
|
||||
if query.Has("after") {
|
||||
after, parseErr := strconv.ParseInt(query.Get("after"), 10, 64)
|
||||
if parseErr != nil {
|
||||
http.Error(w, "bad after", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
revisions, err = s.store.RevisionsAfter(r.Context(), key, query.Get("path"), after)
|
||||
} else {
|
||||
revisions, err = s.store.Revisions(r.Context(), key, query.Get("path"))
|
||||
}
|
||||
if err != nil {
|
||||
writeError(w, err)
|
||||
return
|
||||
@@ -319,8 +347,9 @@ func (s *Server) push(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, err)
|
||||
return
|
||||
}
|
||||
s.publish(protocol.Event{Repo: key, Seq: seq})
|
||||
writeJSON(w, http.StatusCreated, protocol.Event{Repo: key, Seq: seq})
|
||||
event := protocol.Event{Repo: key, Seq: seq, Author: push.Author}
|
||||
s.publish(event)
|
||||
writeJSON(w, http.StatusCreated, event)
|
||||
}
|
||||
|
||||
func (s *Server) blob(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -370,14 +399,17 @@ func (s *Server) events(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "streaming unsupported", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
machineID, _ := r.Context().Value(machineKey{}).(int64)
|
||||
subscriber := make(chan protocol.Event, 16)
|
||||
s.mu.Lock()
|
||||
s.subscribers[subscriber] = struct{}{}
|
||||
s.mu.Unlock()
|
||||
s.track(machineID, 1)
|
||||
defer func() {
|
||||
s.mu.Lock()
|
||||
delete(s.subscribers, subscriber)
|
||||
s.mu.Unlock()
|
||||
s.track(machineID, -1)
|
||||
}()
|
||||
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
@@ -391,6 +423,7 @@ func (s *Server) events(w http.ResponseWriter, r *http.Request) {
|
||||
case <-r.Context().Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
s.track(machineID, 0)
|
||||
fmt.Fprint(w, ": ping\n\n")
|
||||
case event := <-subscriber:
|
||||
data, _ := json.Marshal(event)
|
||||
|
||||
Reference in new issue
Block a user