summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfy-J <[email protected]>2019-01-05 15:51:15 +0300
committerWolfy-J <[email protected]>2019-01-05 15:51:15 +0300
commit6f1a668f5d67bc81d1ac26be84620dc5c87e1581 (patch)
tree2208fb4c411f200e666694e35ef6eb48b3c5abc8
parent94f4083b1d85d0a45b48cbf80d83e3049c30096e (diff)
override config flags
-rw-r--r--cmd/rr/cmd/root.go87
-rw-r--r--cmd/util/config.go114
-rw-r--r--service/http/handler.go22
-rw-r--r--service/http/handler_test.go47
-rw-r--r--service/http/request.go4
-rw-r--r--service/http/service.go5
-rw-r--r--service/http/uploads_test.go9
-rw-r--r--util/fasttime.go41
-rw-r--r--util/fasttime_test.go47
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()
- }
-}