diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6581845 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/example/data diff --git a/Makefile b/Makefile index d527291..f2422dd 100644 --- a/Makefile +++ b/Makefile @@ -5,4 +5,7 @@ build: test: go test -v './...' -.PHONY: build test +clean: + rm -r $(GOPATH)/pkg + +.PHONY: build test clean diff --git a/example/fixtures/articles.go b/example/fixtures/articles.go index df6eb0e..a681dd2 100644 --- a/example/fixtures/articles.go +++ b/example/fixtures/articles.go @@ -6,7 +6,7 @@ import ( "time" ) -const C = 50 +const C = 100000 func main() { diff --git a/example/server/main.go b/example/server/main.go index 5bd38c4..1b0f363 100644 --- a/example/server/main.go +++ b/example/server/main.go @@ -4,6 +4,7 @@ import ( "simplex.sh/container" _ "simplex.sh/example" _ "simplex.sh/store/file" + _ "simplex.sh/store/redis" ) func main() { container.CLI() } diff --git a/shttp/route_handler.go b/shttp/route_handler.go index fb93005..683e713 100644 --- a/shttp/route_handler.go +++ b/shttp/route_handler.go @@ -47,7 +47,7 @@ func (m *RouteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } if rule.Address != "" { - body, err = m.store.Get("blobs/" + rule.Address) + body, err = m.store.GetBlob("blobs/" + rule.Address) if err != nil { http.Error(w, err.Error(), 500) return @@ -75,7 +75,7 @@ func (m *RouteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (m *RouteHandler) load_routing_table() error { - r, err := m.store.Get("route_table.json") + r, err := m.store.GetBlob("route_table.json") if err != nil { if store.IsNotFound(err) { m.table = map[string][]route_rule{} diff --git a/shttp/terminator.go b/shttp/terminator.go index a9cda07..dafdb5d 100644 --- a/shttp/terminator.go +++ b/shttp/terminator.go @@ -58,7 +58,7 @@ func (r *terminator) Commit() error { func (t *terminator) write_route_table() { defer t.wg.Done() - w, err := t.tx.DstStore().Set("route_table.json") + w, err := t.tx.DstStore().SetBlob("route_table.json") if err != nil { t.err.Add(err) return @@ -106,7 +106,7 @@ func (t *terminator) document_writer(c <-chan *document) { store := t.tx.DstStore() for doc := range c { - w, err := store.Set("blobs/" + doc.Digest) + w, err := store.SetBlob("blobs/" + doc.Digest) if err != nil { t.err.Add(err) continue diff --git a/static/tx_coll.go b/static/tx_coll.go index 7b1b4b9..b80bfec 100644 --- a/static/tx_coll.go +++ b/static/tx_coll.go @@ -34,7 +34,7 @@ func (tx *Tx) Coll(name string, typ interface{}) *C { et = et.Elem() } - r, err := tx.src.Get(name + ".json") + r, err := tx.src.GetBlob(name + ".json") if err != nil { return err } diff --git a/store/cache.go b/store/cache.go index 5289d02..8c8eeb5 100644 --- a/store/cache.go +++ b/store/cache.go @@ -18,11 +18,11 @@ func Cache(sub Store) Store { } } -func (c *cache_store) Set(name string) (io.WriteCloser, error) { - return c.store.Set(name) +func (c *cache_store) SetBlob(name string) (io.WriteCloser, error) { + return c.store.SetBlob(name) } -func (c *cache_store) Get(name string) (io.ReadCloser, error) { +func (c *cache_store) GetBlob(name string) (io.ReadCloser, error) { if data, p := c.entries[name]; p { return ioutil.NopCloser(bytes.NewReader(data)), nil } @@ -33,7 +33,7 @@ func (c *cache_store) Get(name string) (io.ReadCloser, error) { err error ) - upstream, err = c.store.Get(name) + upstream, err = c.store.GetBlob(name) if err != nil { return upstream, err } diff --git a/store/file/file.go b/store/file/store.go similarity index 87% rename from store/file/file.go rename to store/file/store.go index 55eb171..6d46061 100644 --- a/store/file/file.go +++ b/store/file/store.go @@ -28,7 +28,7 @@ func Open(u *url.URL) (store.Store, error) { type file_store_t string -func (f file_store_t) Get(name string) (io.ReadCloser, error) { +func (f file_store_t) GetBlob(name string) (io.ReadCloser, error) { r, err := os.Open(path.Join(string(f), name)) if err != nil { @@ -42,7 +42,7 @@ func (f file_store_t) Get(name string) (io.ReadCloser, error) { return r, err } -func (f file_store_t) Set(name string) (io.WriteCloser, error) { +func (f file_store_t) SetBlob(name string) (io.WriteCloser, error) { p := path.Join(string(f), name) err := os.MkdirAll(path.Dir(p), 0755) diff --git a/store/redis/store.go b/store/redis/store.go new file mode 100644 index 0000000..ee5420f --- /dev/null +++ b/store/redis/store.go @@ -0,0 +1,70 @@ +package redis + +import ( + "bytes" + "github.com/simonz05/godis/redis" + "io" + "io/ioutil" + "net/url" + "path" + "simplex.sh/store" +) + +func init() { + store.Register("redis", Open) +} + +type store_t struct { + conn *redis.Client + prefix string +} + +type setter struct { + io.Writer + conn *redis.Client + key string +} + +func Open(u *url.URL) (store.Store, error) { + var ( + addr = "tcp:" + u.Host + pass = "" + prefix = "sx:" + conn *redis.Client + ) + + if ui := u.User; ui != nil { + pass, _ = ui.Password() + } + + prefix += u.Path + prefix = path.Clean(prefix) + + conn = redis.New(addr, 0, pass) + + return &store_t{conn, prefix}, nil +} + +func (s *store_t) GetBlob(name string) (io.ReadCloser, error) { + key := path.Join(s.prefix, name) + elem, err := s.conn.Get(key) + + if err != nil { + return nil, err + } + + if elem == nil { + return nil, store.NotFoundError(name) + } + + return ioutil.NopCloser(bytes.NewReader(elem.Bytes())), err +} + +func (s *store_t) SetBlob(name string) (io.WriteCloser, error) { + key := path.Join(s.prefix, name) + return &setter{bytes.NewBuffer(nil), s.conn, key}, nil +} + +func (s *setter) Close() error { + return s.conn.Set(s.key, s.Writer.(*bytes.Buffer).Bytes()) +} diff --git a/store/store.go b/store/store.go index 572b4d3..390b5db 100644 --- a/store/store.go +++ b/store/store.go @@ -5,8 +5,8 @@ import ( ) type Store interface { - Get(name string) (io.ReadCloser, error) - Set(name string) (io.WriteCloser, error) + GetBlob(name string) (io.ReadCloser, error) + SetBlob(name string) (io.WriteCloser, error) } type notfound_error struct { diff --git a/store/sub.go b/store/sub.go index ee788bc..e177013 100644 --- a/store/sub.go +++ b/store/sub.go @@ -14,10 +14,10 @@ func SubStore(store Store, prefix string) Store { return &sub_store_t{prefix, store} } -func (s *sub_store_t) Get(name string) (io.ReadCloser, error) { - return s.store.Get(path.Join(s.prefix, name)) +func (s *sub_store_t) GetBlob(name string) (io.ReadCloser, error) { + return s.store.GetBlob(path.Join(s.prefix, name)) } -func (s *sub_store_t) Set(name string) (io.WriteCloser, error) { - return s.store.Set(path.Join(s.prefix, name)) +func (s *sub_store_t) SetBlob(name string) (io.WriteCloser, error) { + return s.store.SetBlob(path.Join(s.prefix, name)) }