Sfoglia il codice sorgente

Making this whole thing simpler.

Kelly Norton 10 anni fa
parent
commit
a64b12d92a
5 ha cambiato i file con 77 aggiunte e 71 eliminazioni
  1. 12 13
      context/context.go
  2. 1 1
      context/context_test.go
  3. 3 2
      pub/index.js
  4. 0 0
      web/bindata.go
  5. 61 55
      web/web.go

+ 12 - 13
context/context.go

@@ -15,9 +15,8 @@ import (
 )
 
 const (
-	routesDbFilename        = "routes.db"
-	idLogFilename           = "id"
-	idBatchSize      uint64 = 1000
+	routesDbFilename = "routes.db"
+	idLogFilename    = "id"
 )
 
 // Route ...
@@ -80,7 +79,7 @@ func commit(filename string, id uint64) error {
 
 func load(filename string) (uint64, error) {
 	if _, err := os.Stat(filename); err != nil {
-		return 0, commit(filename, idBatchSize)
+		return 0, commit(filename, 0)
 	}
 
 	r, err := os.Open(filename)
@@ -148,6 +147,11 @@ func (c *Context) Put(key string, rt *Route) error {
 	return c.db.Put([]byte(key), buf.Bytes(), &opt.WriteOptions{Sync: true})
 }
 
+// Del ...
+func (c *Context) Del(key string) error {
+	return c.db.Delete([]byte(key), &opt.WriteOptions{Sync: true})
+}
+
 func (c *Context) commit(id uint64) error {
 	w, err := os.Create(filepath.Join(c.path, idLogFilename))
 	if err != nil {
@@ -167,16 +171,11 @@ func (c *Context) NextID() (uint64, error) {
 	c.lck.Lock()
 	defer c.lck.Unlock()
 
-	// when we hit a batch boundary, we will commit all ids until the next
-	// boundary. If we crash, we'll just throw away a batch of ids in the worst
-	// case.
-	if c.id%idBatchSize == 0 {
-		if err := commit(filepath.Join(c.path, idLogFilename), c.id+idBatchSize); err != nil {
-			return 0, err
-		}
-	}
-
 	c.id++
 
+	if err := commit(filepath.Join(c.path, idLogFilename), c.id); err != nil {
+		return 0, err
+	}
+
 	return c.id, nil
 }

+ 1 - 1
context/context_test.go

@@ -62,7 +62,7 @@ func TestNextID(t *testing.T) {
 	}
 
 	var e uint64 = 1
-	for i, n := 0, 2*int(idBatchSize)+5; i < n; i++ {
+	for i := 0; i < 501; i++ {
 		r, err := ctx.NextID()
 		if err != nil {
 			t.Fatal(err)

+ 3 - 2
pub/index.js

@@ -52,7 +52,8 @@ var form = $('form').on('submit', function(e) {
   }).success(function(data) {
     var url = data.url || '';
     if (url) {
-      showLink(name);
+      history.replaceState({}, null, '/edit/' + data.name);
+      showLink(data.name);
     }
   });
 });
@@ -61,4 +62,4 @@ window.addEventListener('resize', resize);
 resize();
 load();
 
-})();
+})();

File diff suppressed because it is too large
+ 0 - 0
web/bindata.go


+ 61 - 55
web/web.go

@@ -13,7 +13,10 @@ import (
 	"github.com/syndtr/goleveldb/leveldb"
 )
 
-const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+const (
+	alpha  = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	prefix = ":"
+)
 
 func encodeID(id uint64) string {
 	n := uint64(len(alpha))
@@ -88,51 +91,74 @@ type apiHandler struct {
 	ctx *context.Context
 }
 
-func (h *apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+func apiPost(ctx *context.Context, w http.ResponseWriter, r *http.Request) {
 	p := parseName("/api/url/", r.URL.Path)
-	if p == "" {
-		writeJSONError(w,
-			http.StatusText(http.StatusNotFound),
-			http.StatusNotFound)
-		return
-	}
 
-	if r.Method == "POST" {
-		var req struct {
-			URL string `json:"url"`
-		}
+	var req struct {
+		URL string `json:"url"`
+	}
 
-		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
-			writeJSONError(w, "invalid json", http.StatusBadRequest)
-			return
-		}
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		writeJSONError(w, "invalid json", http.StatusBadRequest)
+		return
+	}
 
-		if req.URL == "" {
+	if req.URL == "" {
+		if p == "" {
 			writeJSONError(w, "url required", http.StatusBadRequest)
 			return
 		}
 
-		rt := context.Route{
-			URL:  req.URL,
-			Time: time.Now(),
-		}
-
-		if err := h.ctx.Put(p, &rt); err != nil {
+		if err := ctx.Del(p); err != nil {
 			log.Panic(err)
 		}
+		return
+	}
 
-		writeJSONRoute(w, p, &rt)
-	} else if r.Method == "GET" {
-		rt, err := h.ctx.Get(p)
-		if err == leveldb.ErrNotFound {
-			writeJSONError(w, "no such route", http.StatusNotFound)
-			return
-		} else if err != nil {
+	if p == "" {
+		id, err := ctx.NextID()
+		if err != nil {
 			log.Panic(err)
 		}
+		p = encodeID(id)
+	}
+
+	rt := context.Route{
+		URL:  req.URL,
+		Time: time.Now(),
+	}
 
-		writeJSONRoute(w, p, rt)
-	} else {
+	if err := ctx.Put(p, &rt); err != nil {
+		log.Panic(err)
+	}
+
+	writeJSONRoute(w, p, &rt)
+}
+
+func apiGet(ctx *context.Context, w http.ResponseWriter, r *http.Request) {
+	p := parseName("/api/url/", r.URL.Path)
+	if p == "" {
+		writeJSONError(w, "no such route", http.StatusNotFound)
+	}
+
+	rt, err := ctx.Get(p)
+	if err == leveldb.ErrNotFound {
+		writeJSONError(w, "no such route", http.StatusNotFound)
+		return
+	} else if err != nil {
+		log.Panic(err)
+	}
+
+	writeJSONRoute(w, p, rt)
+}
+
+func (h *apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	switch r.Method {
+	case "POST":
+		apiPost(h.ctx, w, r)
+	case "GET":
+		apiGet(h.ctx, w, r)
+	default:
 		writeJSONError(w,
 			http.StatusText(http.StatusMethodNotAllowed),
 			http.StatusMethodNotAllowed)
@@ -145,19 +171,13 @@ type defaultHandler struct {
 
 func (h *defaultHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	p := parseName("/", r.URL.Path)
-
 	if p == "" {
-		id, err := h.ctx.NextID()
-		if err != nil {
-			log.Panic(err)
-		}
-
-		http.Redirect(w, r,
-			fmt.Sprintf("/edit/%s", encodeID(id)),
-			http.StatusTemporaryRedirect)
+		http.Redirect(w, r, "/edit/", http.StatusTemporaryRedirect)
 		return
 	}
 
+	// TODO(knorton): remove the special prefix
+
 	rt, err := h.ctx.Get(p)
 	if err == leveldb.ErrNotFound {
 		http.Redirect(w, r,
@@ -178,20 +198,6 @@ type editHandler struct {
 }
 
 func (h *editHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	p := parseName("/edit/", r.URL.Path)
-
-	if p == "" {
-		id, err := h.ctx.NextID()
-		if err != nil {
-			log.Panic(err)
-		}
-
-		http.Redirect(w, r,
-			fmt.Sprintf("/edit/%s", encodeID(id)),
-			http.StatusTemporaryRedirect)
-		return
-	}
-
 	serveAsset(w, r, "index.html")
 }
 

Some files were not shown because too many files changed in this diff