From 0e87800ddccc8e7650b985a9974c40982669d51c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisendo=CC=88rfer?= Date: Thu, 2 May 2013 18:29:42 +0200 Subject: [PATCH] Initial refactoring, WIP --- src/cmd/tusd/main.go | 41 ++++++++++++++++++++++++---- src/{cmd/tusd => http}/chunk.go | 2 +- src/{cmd/tusd => http}/chunk_test.go | 2 +- src/{cmd/tusd => http}/data_store.go | 8 ++++-- src/http/handler.go | 31 ++++++++++++++++++--- 5 files changed, 71 insertions(+), 13 deletions(-) rename src/{cmd/tusd => http}/chunk.go (98%) rename src/{cmd/tusd => http}/chunk_test.go (99%) rename src/{cmd/tusd => http}/data_store.go (93%) diff --git a/src/cmd/tusd/main.go b/src/cmd/tusd/main.go index 083381b..5b8a619 100644 --- a/src/cmd/tusd/main.go +++ b/src/cmd/tusd/main.go @@ -1,10 +1,12 @@ package main import ( - "log" tushttp "github.com/tus/tusd/src/http" + "log" "net/http" "os" + "path/filepath" + "strconv" ) func main() { @@ -12,12 +14,41 @@ func main() { log.Printf("tusd started") addr := ":1080" - if port := os.Getenv("TUSD_PORT"); port != "" { - addr = ":" + port + if envPort := os.Getenv("TUSD_PORT"); envPort != "" { + addr = ":" + envPort } - log.Printf("servering clients at http://localhost%s", addr) - handler := tushttp.NewHandler() + maxSize := int64(1024 * 1024 * 1024) + if envMaxSize := os.Getenv("TUSD_DATA_STORE_MAXSIZE"); envMaxSize != "" { + parsed, err := strconv.ParseInt(envMaxSize, 10, 64) + if err != nil { + panic("bad TUSD_DATA_STORE_MAXSIZE: " + err.Error()) + } + maxSize = parsed + } + + dir := os.Getenv("TUSD_DATA_DIR") + if dir == "" { + if workingDir, err := os.Getwd(); err != nil { + panic(err) + } else { + dir = filepath.Join(workingDir, "tus_data") + } + } + + config := tushttp.HandlerConfig{ + Dir: dir, + MaxSize: maxSize, + } + + log.Printf("handler config: %+v", config) + + handler, err := tushttp.NewHandler(config) + if err != nil { + panic(err) + } + + log.Printf("servering clients at http://localhost%s", addr) if err := http.ListenAndServe(addr, handler); err != nil { panic(err) } diff --git a/src/cmd/tusd/chunk.go b/src/http/chunk.go similarity index 98% rename from src/cmd/tusd/chunk.go rename to src/http/chunk.go index f350ccc..7de5bd3 100644 --- a/src/cmd/tusd/chunk.go +++ b/src/http/chunk.go @@ -1,4 +1,4 @@ -package main +package http import ( "sort" diff --git a/src/cmd/tusd/chunk_test.go b/src/http/chunk_test.go similarity index 99% rename from src/cmd/tusd/chunk_test.go rename to src/http/chunk_test.go index 59eecc1..3fc5838 100644 --- a/src/cmd/tusd/chunk_test.go +++ b/src/http/chunk_test.go @@ -1,4 +1,4 @@ -package main +package http import ( "fmt" diff --git a/src/cmd/tusd/data_store.go b/src/http/data_store.go similarity index 93% rename from src/cmd/tusd/data_store.go rename to src/http/data_store.go index f7590da..30a2a42 100644 --- a/src/cmd/tusd/data_store.go +++ b/src/http/data_store.go @@ -1,4 +1,4 @@ -package main +package http import ( "encoding/json" @@ -18,7 +18,7 @@ type DataStore struct { maxSize int64 } -func NewDataStore(dir string, maxSize int64) *DataStore { +func newDataStore(dir string, maxSize int64) *DataStore { store := &DataStore{dir: dir, maxSize: maxSize} go store.gcLoop() return store @@ -139,6 +139,10 @@ func (s *DataStore) logPath(id string) string { return path.Join(s.dir, id) + ".log" } +// TODO: This works for now, but it would be better if we would trigger gc() +// manually whenever a storage operation will need more space, telling gc() how +// much space we need. If the amount of space required fits into the max, we +// can simply ignore the gc request, otherwise delete just as much as we need. func (s *DataStore) gcLoop() { for { if before, after, err := s.gc(); err != nil { diff --git a/src/http/handler.go b/src/http/handler.go index f33e0ae..3204f0d 100644 --- a/src/http/handler.go +++ b/src/http/handler.go @@ -1,14 +1,37 @@ package http import ( + "log" "net/http" + "os" ) -func NewHandler() *Handler { - return &Handler{} +type HandlerConfig struct{ + // Dir points to a filesystem path used by tus to store uploaded and partial + // files. Will be created if does not exist yet. Required. + Dir string + + // MaxSize defines how many bytes may be stored inside Dir. Exceeding this + // limit will cause the oldest upload files to be deleted until enough space + // is available again. Required. + MaxSize int64 } -type Handler struct {} +func NewHandler(config HandlerConfig) (*Handler, error) { + // Ensure the data store directory exists + if err := os.MkdirAll(config.Dir, 0777); err != nil { + return nil, err + } -func (h *Handler) ServeHTTP(http.ResponseWriter, *http.Request) { + return &Handler{ + store: newDataStore(config.Dir, config.MaxSize), + }, nil +} + +type Handler struct{ + store *DataStore +} + +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + log.Printf("request: %s %s", r.Method, r.URL.RequestURI()) }