diff options
author | Wolfy-J <[email protected]> | 2019-01-05 15:51:15 +0300 |
---|---|---|
committer | Wolfy-J <[email protected]> | 2019-01-05 15:51:15 +0300 |
commit | 6f1a668f5d67bc81d1ac26be84620dc5c87e1581 (patch) | |
tree | 2208fb4c411f200e666694e35ef6eb48b3c5abc8 | |
parent | 94f4083b1d85d0a45b48cbf80d83e3049c30096e (diff) |
override config flags
-rw-r--r-- | cmd/rr/cmd/root.go | 87 | ||||
-rw-r--r-- | cmd/util/config.go | 114 | ||||
-rw-r--r-- | service/http/handler.go | 22 | ||||
-rw-r--r-- | service/http/handler_test.go | 47 | ||||
-rw-r--r-- | service/http/request.go | 4 | ||||
-rw-r--r-- | service/http/service.go | 5 | ||||
-rw-r--r-- | service/http/uploads_test.go | 9 | ||||
-rw-r--r-- | util/fasttime.go | 41 | ||||
-rw-r--r-- | util/fasttime_test.go | 47 |
9 files changed, 145 insertions, 231 deletions
diff --git a/cmd/rr/cmd/root.go b/cmd/rr/cmd/root.go index 15a004e0..ceeeb840 100644 --- a/cmd/rr/cmd/root.go +++ b/cmd/rr/cmd/root.go @@ -23,16 +23,15 @@ package cmd import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/spiral/roadrunner/cmd/util" "github.com/spiral/roadrunner/service" "os" - "path/filepath" ) // Service bus for all the commands. var ( - cfgFile string + cfgFile string + override []string // Verbose enables verbosity mode (container specific). Verbose bool @@ -59,26 +58,6 @@ var ( } ) -// ViperWrapper provides interface bridge between v configs and service.Config. -type ViperWrapper struct { - v *viper.Viper -} - -// Get nested config section (sub-map), returns nil if section not found. -func (w *ViperWrapper) Get(key string) service.Config { - sub := w.v.Sub(key) - if sub == nil { - return nil - } - - return &ViperWrapper{sub} -} - -// Unmarshal unmarshal config data into given struct. -func (w *ViperWrapper) Unmarshal(out interface{}) error { - return w.v.Unmarshal(out) -} - // Execute adds all child commands to the CLI command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the CLI. func Execute() { @@ -92,60 +71,28 @@ func init() { CLI.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "Verbose output") CLI.PersistentFlags().BoolVarP(&Debug, "debug", "d", false, "debug mode") CLI.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is .rr.yaml)") + CLI.PersistentFlags().StringArrayVarP( + &override, + "override", + "o", + nil, + "override config value (dot.notation=value)", + ) cobra.OnInitialize(func() { if Verbose { Logger.SetLevel(logrus.DebugLevel) } - if cfg := initConfig(cfgFile, []string{"."}, ".rr"); cfg != nil { - if err := Container.Init(cfg); err != nil { - util.Printf("<red+hb>Error:</reset> <red>%s</reset>\n", err) - os.Exit(1) - } + cfg, err := util.LoadConfig(cfgFile, []string{"."}, ".rr", override) + if err != nil { + Logger.Warnf("config: %s", err) + return } - }) -} - -func initConfig(cfgFile string, path []string, name string) service.Config { - cfg := viper.New() - - if cfgFile != "" { - if absPath, err := filepath.Abs(cfgFile); err == nil { - cfgFile = absPath - // force working absPath related to config file - if err := os.Chdir(filepath.Dir(absPath)); err != nil { - Logger.Error(err) - } + if err := Container.Init(cfg); err != nil { + util.Printf("<red+hb>Error:</reset> <red>%s</reset>\n", err) + os.Exit(1) } - - // Use cfg file from the flag. - cfg.SetConfigFile(cfgFile) - - if dir, err := filepath.Abs(cfgFile); err == nil { - // force working absPath related to config file - if err := os.Chdir(filepath.Dir(dir)); err != nil { - Logger.Error(err) - } - } - } else { - // automatic location - for _, p := range path { - cfg.AddConfigPath(p) - } - - cfg.SetConfigName(name) - } - - // read in environment variables that match - cfg.AutomaticEnv() - - // If a cfg file is found, read it in. - if err := cfg.ReadInConfig(); err != nil { - Logger.Warnf("config: %s", err) - return nil - } - - return &ViperWrapper{cfg} + }) } diff --git a/cmd/util/config.go b/cmd/util/config.go new file mode 100644 index 00000000..a829f44c --- /dev/null +++ b/cmd/util/config.go @@ -0,0 +1,114 @@ +package util + +import ( + "fmt" + "github.com/spf13/viper" + "github.com/spiral/roadrunner/service" + "os" + "path/filepath" + "strings" +) + +// configWrapper provides interface bridge between v configs and service.Config. +type configWrapper struct { + v *viper.Viper +} + +// Get nested config section (sub-map), returns nil if section not found. +func (w *configWrapper) Get(key string) service.Config { + sub := w.v.Sub(key) + if sub == nil { + return nil + } + + return &configWrapper{sub} +} + +// Unmarshal unmarshal config data into given struct. +func (w *configWrapper) Unmarshal(out interface{}) error { + return w.v.Unmarshal(out) +} + +// LoadConfig config and merge it's values with set of flags. +func LoadConfig(cfgFile string, path []string, name string, flags []string) (*configWrapper, error) { + cfg := viper.New() + + if cfgFile != "" { + if absPath, err := filepath.Abs(cfgFile); err == nil { + cfgFile = absPath + + // force working absPath related to config file + if err := os.Chdir(filepath.Dir(absPath)); err != nil { + return nil, err + } + } + + // Use cfg file from the flag. + cfg.SetConfigFile(cfgFile) + + if dir, err := filepath.Abs(cfgFile); err == nil { + // force working absPath related to config file + if err := os.Chdir(filepath.Dir(dir)); err != nil { + return nil, err + } + } + } else { + // automatic location + for _, p := range path { + cfg.AddConfigPath(p) + } + + cfg.SetConfigName(name) + } + + // read in environment variables that match + cfg.AutomaticEnv() + + // If a cfg file is found, read it in. + if err := cfg.ReadInConfig(); err != nil { + return nil, err + } + + if len(flags) != 0 { + for _, f := range flags { + k, v, err := parseFlag(f) + if err != nil { + return nil, err + } + + cfg.Set(k, v) + } + + merged := viper.New() + + // we have to copy all the merged values into new config in order normalize it (viper bug?) + if err := merged.MergeConfigMap(cfg.AllSettings()); err != nil { + return nil, err + } + + return &configWrapper{merged}, nil + } + + return &configWrapper{cfg}, nil +} + +func parseFlag(flag string) (string, string, error) { + if !strings.Contains(flag, "=") { + return "", "", fmt.Errorf("invalid flag `%s`", flag) + } + + parts := strings.SplitN(strings.TrimLeft(flag, " \"'`"), "=", 2) + + return strings.Trim(parts[0], " \n\t"), parseValue(strings.Trim(parts[1], " \n\t")), nil +} + +func parseValue(value string) string { + escape := []rune(value)[0] + + if escape == '"' || escape == '\'' || escape == '`' { + value = strings.Trim(value, string(escape)) + value = strings.Replace(value, fmt.Sprintf("\\%s", string(escape)), string(escape), -1) + } + + return value +} diff --git a/service/http/handler.go b/service/http/handler.go index 8ff1bdeb..8cebc42a 100644 --- a/service/http/handler.go +++ b/service/http/handler.go @@ -3,7 +3,6 @@ package http import ( "github.com/pkg/errors" "github.com/spiral/roadrunner" - "github.com/spiral/roadrunner/util" "net/http" "strconv" "sync" @@ -27,12 +26,13 @@ type ErrorEvent struct { Error error // event timings - start, end int64 + start time.Time + elapsed time.Duration } // Elapsed returns duration of the invocation. func (e *ErrorEvent) Elapsed() time.Duration { - return time.Duration(e.end - e.start) + return e.elapsed } // ResponseEvent represents singular http response event. @@ -44,18 +44,18 @@ type ResponseEvent struct { Response *Response // event timings - start, end int64 + start time.Time + elapsed time.Duration } // Elapsed returns duration of the invocation. func (e *ResponseEvent) Elapsed() time.Duration { - return time.Duration(e.end - e.start) + return e.elapsed } // Handler serves http connections to underlying PHP application using PSR-7 protocol. Context will include request headers, // parsed files and query, payload will include parsed form dataTree (if any). type Handler struct { - ft *util.FastTime cfg *Config rr *roadrunner.Server mul sync.Mutex @@ -72,7 +72,7 @@ func (h *Handler) Listen(l func(event int, ctx interface{})) { // mdwr serve using PSR-7 requests passed to underlying application. Attempts to serve static files first if enabled. func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - start := h.ft.UnixNano() + start := time.Now() // validating request size if h.cfg.MaxRequest != 0 { @@ -119,16 +119,16 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } // handleError sends error. -func (h *Handler) handleError(w http.ResponseWriter, r *http.Request, err error, start int64) { - h.throw(EventError, &ErrorEvent{Request: r, Error: err, start: start, end: h.ft.UnixNano()}) +func (h *Handler) handleError(w http.ResponseWriter, r *http.Request, err error, start time.Time) { + h.throw(EventError, &ErrorEvent{Request: r, Error: err, start: start, elapsed: time.Since(start)}) w.WriteHeader(500) w.Write([]byte(err.Error())) } // handleResponse triggers response event. -func (h *Handler) handleResponse(req *Request, resp *Response, start int64) { - h.throw(EventResponse, &ResponseEvent{Request: req, Response: resp, start: start, end: h.ft.UnixNano()}) +func (h *Handler) handleResponse(req *Request, resp *Response, start time.Time) { + h.throw(EventResponse, &ResponseEvent{Request: req, Response: resp, start: start, elapsed: time.Since(start)}) } // throw invokes event handler if any. diff --git a/service/http/handler_test.go b/service/http/handler_test.go index d8a15202..770158e5 100644 --- a/service/http/handler_test.go +++ b/service/http/handler_test.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "github.com/spiral/roadrunner" - "github.com/spiral/roadrunner/util" "github.com/stretchr/testify/assert" "io/ioutil" "mime/multipart" @@ -32,7 +31,6 @@ func get(url string) (string, *http.Response, error) { func TestHandler_Echo(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -50,7 +48,6 @@ func TestHandler_Echo(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -69,7 +66,6 @@ func TestHandler_Echo(t *testing.T) { func Test_HandlerErrors(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -87,7 +83,6 @@ func Test_HandlerErrors(t *testing.T) { }, }), } - defer h.ft.Stop() wr := httptest.NewRecorder() rq := httptest.NewRequest("POST", "/", bytes.NewBuffer([]byte("data"))) @@ -98,7 +93,6 @@ func Test_HandlerErrors(t *testing.T) { func Test_Handler_JSON_error(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -116,7 +110,6 @@ func Test_Handler_JSON_error(t *testing.T) { }, }), } - defer h.ft.Stop() wr := httptest.NewRecorder() rq := httptest.NewRequest("POST", "/", bytes.NewBuffer([]byte("{sd"))) @@ -129,7 +122,6 @@ func Test_Handler_JSON_error(t *testing.T) { func TestHandler_Headers(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -147,7 +139,6 @@ func TestHandler_Headers(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -178,7 +169,6 @@ func TestHandler_Headers(t *testing.T) { func TestHandler_Empty_User_Agent(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -196,7 +186,6 @@ func TestHandler_Empty_User_Agent(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -226,7 +215,6 @@ func TestHandler_Empty_User_Agent(t *testing.T) { func TestHandler_User_Agent(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -244,7 +232,6 @@ func TestHandler_User_Agent(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -274,7 +261,6 @@ func TestHandler_User_Agent(t *testing.T) { func TestHandler_Cookies(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -292,7 +278,6 @@ func TestHandler_Cookies(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -327,7 +312,6 @@ func TestHandler_Cookies(t *testing.T) { func TestHandler_JsonPayload_POST(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -345,7 +329,6 @@ func TestHandler_JsonPayload_POST(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -379,7 +362,6 @@ func TestHandler_JsonPayload_POST(t *testing.T) { func TestHandler_JsonPayload_PUT(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -397,7 +379,6 @@ func TestHandler_JsonPayload_PUT(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -427,7 +408,6 @@ func TestHandler_JsonPayload_PUT(t *testing.T) { func TestHandler_JsonPayload_PATCH(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -445,7 +425,6 @@ func TestHandler_JsonPayload_PATCH(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -475,7 +454,6 @@ func TestHandler_JsonPayload_PATCH(t *testing.T) { func TestHandler_FormData_POST(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -493,7 +471,6 @@ func TestHandler_FormData_POST(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -535,7 +512,6 @@ func TestHandler_FormData_POST(t *testing.T) { func TestHandler_FormData_PUT(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -553,7 +529,6 @@ func TestHandler_FormData_PUT(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -595,7 +570,6 @@ func TestHandler_FormData_PUT(t *testing.T) { func TestHandler_FormData_PATCH(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -613,7 +587,6 @@ func TestHandler_FormData_PATCH(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -655,7 +628,6 @@ func TestHandler_FormData_PATCH(t *testing.T) { func TestHandler_Multipart_POST(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -673,7 +645,6 @@ func TestHandler_Multipart_POST(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -719,7 +690,6 @@ func TestHandler_Multipart_POST(t *testing.T) { func TestHandler_Multipart_PUT(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -737,7 +707,6 @@ func TestHandler_Multipart_PUT(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -783,7 +752,6 @@ func TestHandler_Multipart_PUT(t *testing.T) { func TestHandler_Multipart_PATCH(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -801,7 +769,6 @@ func TestHandler_Multipart_PATCH(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -847,7 +814,6 @@ func TestHandler_Multipart_PATCH(t *testing.T) { func TestHandler_Error(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -865,7 +831,6 @@ func TestHandler_Error(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -883,7 +848,6 @@ func TestHandler_Error(t *testing.T) { func TestHandler_Error2(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -901,7 +865,6 @@ func TestHandler_Error2(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -919,7 +882,6 @@ func TestHandler_Error2(t *testing.T) { func TestHandler_Error3(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1, Uploads: &UploadsConfig{ @@ -937,7 +899,6 @@ func TestHandler_Error3(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -966,7 +927,6 @@ func TestHandler_Error3(t *testing.T) { func TestHandler_ResponseDuration(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -984,7 +944,6 @@ func TestHandler_ResponseDuration(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -1017,7 +976,6 @@ func TestHandler_ResponseDuration(t *testing.T) { func TestHandler_ResponseDurationDelayed(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -1035,7 +993,6 @@ func TestHandler_ResponseDurationDelayed(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -1068,7 +1025,6 @@ func TestHandler_ResponseDurationDelayed(t *testing.T) { func TestHandler_ErrorDuration(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -1086,7 +1042,6 @@ func TestHandler_ErrorDuration(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -1118,7 +1073,6 @@ func TestHandler_ErrorDuration(t *testing.T) { func BenchmarkHandler_Listen_Echo(b *testing.B) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -1136,7 +1090,6 @@ func BenchmarkHandler_Listen_Echo(b *testing.B) { }, }), } - defer h.ft.Stop() h.rr.Start() defer h.rr.Stop() diff --git a/service/http/request.go b/service/http/request.go index eb5c05bd..ca7d7c41 100644 --- a/service/http/request.go +++ b/service/http/request.go @@ -40,10 +40,10 @@ type Request struct { // Cookies contains list of request cookies. Cookies map[string]string `json:"cookies"` - // RawQuery contains non parsed query string (to be parsed on php end). + // RawQuery contains non parsed query string (to be parsed on php elapsed). RawQuery string `json:"rawQuery"` - // Parsed indicates that request body has been parsed on RR end. + // Parsed indicates that request body has been parsed on RR elapsed. Parsed bool `json:"parsed"` // Uploads contains list of uploaded files, their names, sized and associations with temporary files. diff --git a/service/http/service.go b/service/http/service.go index eb97233d..ad59f887 100644 --- a/service/http/service.go +++ b/service/http/service.go @@ -7,13 +7,11 @@ import ( "github.com/spiral/roadrunner/service/env" "github.com/spiral/roadrunner/service/http/attributes" "github.com/spiral/roadrunner/service/rpc" - "github.com/spiral/roadrunner/util" "golang.org/x/net/http2" "net/http" "net/url" "strings" "sync" - "time" ) const ( @@ -79,9 +77,8 @@ func (s *Service) Serve() error { s.rr = roadrunner.NewServer(s.cfg.Workers) s.rr.Listen(s.throw) - s.handler = &Handler{ft: util.NewFastTime(time.Microsecond), cfg: s.cfg, rr: s.rr} + s.handler = &Handler{cfg: s.cfg, rr: s.rr} s.handler.Listen(s.throw) - defer s.handler.ft.Stop() s.http = &http.Server{Addr: s.cfg.Address, Handler: s} diff --git a/service/http/uploads_test.go b/service/http/uploads_test.go index 82e7586b..d452f834 100644 --- a/service/http/uploads_test.go +++ b/service/http/uploads_test.go @@ -7,7 +7,6 @@ import ( "encoding/hex" "encoding/json" "github.com/spiral/roadrunner" - "github.com/spiral/roadrunner/util" "github.com/stretchr/testify/assert" "io" "io/ioutil" @@ -20,7 +19,6 @@ import ( func TestHandler_Upload_File(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -38,7 +36,6 @@ func TestHandler_Upload_File(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -83,7 +80,6 @@ func TestHandler_Upload_File(t *testing.T) { func TestHandler_Upload_NestedFile(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -101,7 +97,6 @@ func TestHandler_Upload_NestedFile(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -146,7 +141,6 @@ func TestHandler_Upload_NestedFile(t *testing.T) { func TestHandler_Upload_File_NoTmpDir(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -164,7 +158,6 @@ func TestHandler_Upload_File_NoTmpDir(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() @@ -209,7 +202,6 @@ func TestHandler_Upload_File_NoTmpDir(t *testing.T) { func TestHandler_Upload_File_Forbids(t *testing.T) { h := &Handler{ - ft: util.NewFastTime(time.Microsecond), cfg: &Config{ MaxRequest: 1024, Uploads: &UploadsConfig{ @@ -227,7 +219,6 @@ func TestHandler_Upload_File_Forbids(t *testing.T) { }, }), } - defer h.ft.Stop() assert.NoError(t, h.rr.Start()) defer h.rr.Stop() diff --git a/util/fasttime.go b/util/fasttime.go deleted file mode 100644 index f1a81333..00000000 --- a/util/fasttime.go +++ /dev/null @@ -1,41 +0,0 @@ -package util - -import ( - "sync/atomic" - "time" -) - -// FastTime provides current unix time using specified resolution with reduced number of syscalls. -type FastTime struct { - last int64 - ticker *time.Ticker -} - -// NewFastTime returns new time provider with given resolution. -func NewFastTime(resolution time.Duration) *FastTime { - ft := &FastTime{ - last: time.Now().UnixNano(), - ticker: time.NewTicker(resolution), - } - - go ft.run() - - return ft -} - -// Stop ticking. -func (ft *FastTime) Stop() { - ft.ticker.Stop() -} - -// UnixNano returns current timestamps. Value might be delayed after current time by specified resolution. -func (ft *FastTime) UnixNano() int64 { - return atomic.LoadInt64(&ft.last) -} - -// consume time values over given resolution. -func (ft *FastTime) run() { - for range ft.ticker.C { - atomic.StoreInt64(&ft.last, time.Now().UnixNano()) - } -} diff --git a/util/fasttime_test.go b/util/fasttime_test.go deleted file mode 100644 index c8ff0e13..00000000 --- a/util/fasttime_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package util - -import ( - "github.com/stretchr/testify/assert" - "testing" - "time" -) - -func TestFTime_UnixNano(t *testing.T) { - ft := NewFastTime(time.Millisecond) - defer ft.Stop() - - var d int64 - - d = time.Now().UnixNano() - ft.UnixNano() - - assert.True(t, d >= 0) - assert.True(t, d <= int64(time.Millisecond*2)) - - time.Sleep(time.Millisecond * 100) - d = time.Now().UnixNano() - ft.UnixNano() - - assert.True(t, d >= 0) - assert.True(t, d <= int64(time.Millisecond*2)) -} - -func Benchmark_FastTime(b *testing.B) { - ft := NewFastTime(time.Microsecond) - defer ft.Stop() - - b.ReportAllocs() - - for n := 0; n < b.N; n++ { - _ = ft.UnixNano() - } -} - -func Benchmark_Time(b *testing.B) { - ft := NewFastTime(time.Microsecond) - defer ft.Stop() - - b.ReportAllocs() - - for n := 0; n < b.N; n++ { - _ = time.Now().UnixNano() - } -} |