build: Enable gometalinter "gosimple" check, improve build.go
This commit is contained in:
parent
47f22ff3e5
commit
d41c131364
134
build.go
134
build.go
|
@ -27,7 +27,6 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -154,6 +153,39 @@ var targets = map[string]target{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// fast linters complete in a fraction of a second and might as well be
|
||||||
|
// run always as part of the build
|
||||||
|
fastLinters = []string{
|
||||||
|
"deadcode",
|
||||||
|
"golint",
|
||||||
|
"ineffassign",
|
||||||
|
"vet",
|
||||||
|
}
|
||||||
|
|
||||||
|
// slow linters take several seconds and are run only as part of the
|
||||||
|
// "metalint" command.
|
||||||
|
slowLinters = []string{
|
||||||
|
"gosimple",
|
||||||
|
"staticcheck",
|
||||||
|
"structcheck",
|
||||||
|
"unused",
|
||||||
|
"varcheck",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which parts of the tree to lint
|
||||||
|
lintDirs = []string{".", "./lib/...", "./cmd/..."}
|
||||||
|
|
||||||
|
// Messages to ignore
|
||||||
|
lintExcludes = []string{
|
||||||
|
".pb.go",
|
||||||
|
"should have comment",
|
||||||
|
"protocol.Vector composite literal uses unkeyed fields",
|
||||||
|
"Use DialContext instead", // Go 1.7
|
||||||
|
"os.SEEK_SET is deprecated", // Go 1.7
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// The "syncthing" target includes a few more files found in the "etc"
|
// The "syncthing" target includes a few more files found in the "etc"
|
||||||
// and "extra" dirs.
|
// and "extra" dirs.
|
||||||
|
@ -203,8 +235,6 @@ func main() {
|
||||||
// which is what you want for maximum error checking during development.
|
// which is what you want for maximum error checking during development.
|
||||||
if flag.NArg() == 0 {
|
if flag.NArg() == 0 {
|
||||||
runCommand("install", targets["all"])
|
runCommand("install", targets["all"])
|
||||||
runCommand("vet", target{})
|
|
||||||
runCommand("lint", target{})
|
|
||||||
} else {
|
} else {
|
||||||
// with any command given but not a target, the target is
|
// with any command given but not a target, the target is
|
||||||
// "syncthing". So "go run build.go install" is "go run build.go install
|
// "syncthing". So "go run build.go install" is "go run build.go install
|
||||||
|
@ -242,6 +272,7 @@ func runCommand(cmd string, target target) {
|
||||||
tags = []string{"noupgrade"}
|
tags = []string{"noupgrade"}
|
||||||
}
|
}
|
||||||
install(target, tags)
|
install(target, tags)
|
||||||
|
metalint(fastLinters, lintDirs)
|
||||||
|
|
||||||
case "build":
|
case "build":
|
||||||
var tags []string
|
var tags []string
|
||||||
|
@ -249,6 +280,7 @@ func runCommand(cmd string, target target) {
|
||||||
tags = []string{"noupgrade"}
|
tags = []string{"noupgrade"}
|
||||||
}
|
}
|
||||||
build(target, tags)
|
build(target, tags)
|
||||||
|
metalint(fastLinters, lintDirs)
|
||||||
|
|
||||||
case "test":
|
case "test":
|
||||||
test("./lib/...", "./cmd/...")
|
test("./lib/...", "./cmd/...")
|
||||||
|
@ -284,28 +316,14 @@ func runCommand(cmd string, target target) {
|
||||||
clean()
|
clean()
|
||||||
|
|
||||||
case "vet":
|
case "vet":
|
||||||
vet("build.go")
|
metalint(fastLinters, lintDirs)
|
||||||
vet("cmd", "lib")
|
|
||||||
|
|
||||||
case "lint":
|
case "lint":
|
||||||
lint(".")
|
metalint(fastLinters, lintDirs)
|
||||||
lint("./cmd/...")
|
|
||||||
lint("./lib/...")
|
|
||||||
|
|
||||||
case "metalint":
|
case "metalint":
|
||||||
if isGometalinterInstalled() {
|
metalint(fastLinters, lintDirs)
|
||||||
dirs := []string{".", "./cmd/...", "./lib/..."}
|
metalint(slowLinters, lintDirs)
|
||||||
ok := gometalinter("deadcode", dirs, "test/util.go")
|
|
||||||
ok = gometalinter("structcheck", dirs) && ok
|
|
||||||
ok = gometalinter("varcheck", dirs) && ok
|
|
||||||
ok = gometalinter("ineffassign", dirs) && ok
|
|
||||||
ok = gometalinter("unused", dirs) && ok
|
|
||||||
ok = gometalinter("staticcheck", dirs) && ok
|
|
||||||
ok = gometalinter("unconvert", dirs) && ok
|
|
||||||
if !ok {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "version":
|
case "version":
|
||||||
fmt.Println(getVersion())
|
fmt.Println(getVersion())
|
||||||
|
@ -373,6 +391,7 @@ func setup() {
|
||||||
"github.com/tsenart/deadcode",
|
"github.com/tsenart/deadcode",
|
||||||
"golang.org/x/net/html",
|
"golang.org/x/net/html",
|
||||||
"golang.org/x/tools/cmd/cover",
|
"golang.org/x/tools/cmd/cover",
|
||||||
|
"honnef.co/go/simple/cmd/gosimple",
|
||||||
"honnef.co/go/staticcheck/cmd/staticcheck",
|
"honnef.co/go/staticcheck/cmd/staticcheck",
|
||||||
"honnef.co/go/unused/cmd/unused",
|
"honnef.co/go/unused/cmd/unused",
|
||||||
}
|
}
|
||||||
|
@ -1009,48 +1028,6 @@ func zipFile(out string, files []archiveFile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func vet(dirs ...string) {
|
|
||||||
params := []string{"tool", "vet", "-all"}
|
|
||||||
params = append(params, dirs...)
|
|
||||||
bs, err := runError("go", params...)
|
|
||||||
|
|
||||||
if len(bs) > 0 {
|
|
||||||
log.Printf("%s", bs)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
if exitStatus(err) == 3 {
|
|
||||||
// Exit code 3, the "vet" tool is not installed
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// A genuine error exit from the vet tool.
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lint(pkg string) {
|
|
||||||
bs, err := runError("golint", pkg)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(`- No golint, not linting. Try "go get -u github.com/golang/lint/golint".`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
analCommentPolicy := regexp.MustCompile(`exported (function|method|const|type|var) [^\s]+ should have comment`)
|
|
||||||
for _, line := range strings.Split(string(bs), "\n") {
|
|
||||||
if line == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if analCommentPolicy.MatchString(line) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.Contains(line, ".pb.go:") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.Println(line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func macosCodesign(file string) {
|
func macosCodesign(file string) {
|
||||||
if pass := os.Getenv("CODESIGN_KEYCHAIN_PASS"); pass != "" {
|
if pass := os.Getenv("CODESIGN_KEYCHAIN_PASS"); pass != "" {
|
||||||
bs, err := runError("security", "unlock-keychain", "-p", pass)
|
bs, err := runError("security", "unlock-keychain", "-p", pass)
|
||||||
|
@ -1070,14 +1047,16 @@ func macosCodesign(file string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func exitStatus(err error) int {
|
func metalint(linters []string, dirs []string) {
|
||||||
if err, ok := err.(*exec.ExitError); ok {
|
ok := true
|
||||||
if ws, ok := err.ProcessState.Sys().(syscall.WaitStatus); ok {
|
if isGometalinterInstalled() {
|
||||||
return ws.ExitStatus()
|
if !gometalinter(linters, dirs, lintExcludes...) {
|
||||||
|
ok = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !ok {
|
||||||
return -1
|
log.Fatal("Build succeeded, but there were lint warnings")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isGometalinterInstalled() bool {
|
func isGometalinterInstalled() bool {
|
||||||
|
@ -1088,10 +1067,12 @@ func isGometalinterInstalled() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func gometalinter(linter string, dirs []string, excludes ...string) bool {
|
func gometalinter(linters []string, dirs []string, excludes ...string) bool {
|
||||||
params := []string{"--disable-all"}
|
params := []string{"--disable-all", "--concurrency=2", "--deadline=300s"}
|
||||||
params = append(params, fmt.Sprintf("--deadline=%ds", 60))
|
|
||||||
params = append(params, "--enable="+linter)
|
for _, linter := range linters {
|
||||||
|
params = append(params, "--enable="+linter)
|
||||||
|
}
|
||||||
|
|
||||||
for _, exclude := range excludes {
|
for _, exclude := range excludes {
|
||||||
params = append(params, "--exclude="+exclude)
|
params = append(params, "--exclude="+exclude)
|
||||||
|
@ -1104,14 +1085,19 @@ func gometalinter(linter string, dirs []string, excludes ...string) bool {
|
||||||
bs, _ := runError("gometalinter", params...)
|
bs, _ := runError("gometalinter", params...)
|
||||||
|
|
||||||
nerr := 0
|
nerr := 0
|
||||||
|
lines := make(map[string]struct{})
|
||||||
for _, line := range strings.Split(string(bs), "\n") {
|
for _, line := range strings.Split(string(bs), "\n") {
|
||||||
if line == "" {
|
if line == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if strings.Contains(line, ".pb.go:") {
|
if _, ok := lines[line]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Println(line)
|
log.Println(line)
|
||||||
|
if strings.Contains(line, "executable file not found") {
|
||||||
|
log.Println(` - Try "go run build.go setup" to install missing tools`)
|
||||||
|
}
|
||||||
|
lines[line] = struct{}{}
|
||||||
nerr++
|
nerr++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,9 @@ func generalID(c *cli.Context) {
|
||||||
|
|
||||||
func generalStatus(c *cli.Context) {
|
func generalStatus(c *cli.Context) {
|
||||||
response := httpGet(c, "system/config/insync")
|
response := httpGet(c, "system/config/insync")
|
||||||
status := make(map[string]interface{})
|
var status struct{ ConfigInSync bool }
|
||||||
json.Unmarshal(responseToBArray(response), &status)
|
json.Unmarshal(responseToBArray(response), &status)
|
||||||
if status["configInSync"] != true {
|
if !status.ConfigInSync {
|
||||||
die("Config out of sync")
|
die("Config out of sync")
|
||||||
}
|
}
|
||||||
fmt.Println("Config in sync")
|
fmt.Println("Config in sync")
|
||||||
|
|
|
@ -85,12 +85,7 @@ func generateOneFile(fd io.ReadSeeker, p1 string, s int64) error {
|
||||||
_ = os.Chmod(p1, os.FileMode(rand.Intn(0777)|0400))
|
_ = os.Chmod(p1, os.FileMode(rand.Intn(0777)|0400))
|
||||||
|
|
||||||
t := time.Now().Add(-time.Duration(rand.Intn(30*86400)) * time.Second)
|
t := time.Now().Add(-time.Duration(rand.Intn(30*86400)) * time.Second)
|
||||||
err = os.Chtimes(p1, t, t)
|
return os.Chtimes(p1, t, t)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func randomName() string {
|
func randomName() string {
|
||||||
|
|
|
@ -381,10 +381,8 @@ func (s *apiService) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *apiService) VerifyConfiguration(from, to config.Configuration) error {
|
func (s *apiService) VerifyConfiguration(from, to config.Configuration) error {
|
||||||
if _, err := net.ResolveTCPAddr("tcp", to.GUI.Address()); err != nil {
|
_, err := net.ResolveTCPAddr("tcp", to.GUI.Address())
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *apiService) CommitConfiguration(from, to config.Configuration) bool {
|
func (s *apiService) CommitConfiguration(from, to config.Configuration) bool {
|
||||||
|
|
|
@ -99,10 +99,7 @@ func (f *FolderConfiguration) CreateMarker() error {
|
||||||
|
|
||||||
func (f *FolderConfiguration) HasMarker() bool {
|
func (f *FolderConfiguration) HasMarker() bool {
|
||||||
_, err := os.Stat(filepath.Join(f.Path(), ".stfolder"))
|
_, err := os.Stat(filepath.Join(f.Path(), ".stfolder"))
|
||||||
if err != nil {
|
return err == nil
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f FolderConfiguration) Description() string {
|
func (f FolderConfiguration) Description() string {
|
||||||
|
|
|
@ -58,10 +58,7 @@ func setup() (*Instance, *BlockFinder) {
|
||||||
func dbEmpty(db *Instance) bool {
|
func dbEmpty(db *Instance) bool {
|
||||||
iter := db.NewIterator(util.BytesPrefix([]byte{KeyTypeBlock}), nil)
|
iter := db.NewIterator(util.BytesPrefix([]byte{KeyTypeBlock}), nil)
|
||||||
defer iter.Release()
|
defer iter.Release()
|
||||||
if iter.Next() {
|
return !iter.Next()
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockMapAddUpdateWipe(t *testing.T) {
|
func TestBlockMapAddUpdateWipe(t *testing.T) {
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
// +build ignore // this is a really tedious test for an old issue
|
// this is a really tedious test for an old issue
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
package db_test
|
package db_test
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ func NewLocal(id protocol.DeviceID, addr string, addrList AddressLister) (Finder
|
||||||
Supervisor: suture.NewSimple("local"),
|
Supervisor: suture.NewSimple("local"),
|
||||||
myID: id,
|
myID: id,
|
||||||
addrList: addrList,
|
addrList: addrList,
|
||||||
localBcastTick: time.Tick(BroadcastInterval),
|
localBcastTick: time.NewTicker(BroadcastInterval).C,
|
||||||
forcedBcastTick: make(chan time.Time),
|
forcedBcastTick: make(chan time.Time),
|
||||||
localBcastStart: time.Now(),
|
localBcastStart: time.Now(),
|
||||||
cache: newCache(),
|
cache: newCache(),
|
||||||
|
|
|
@ -247,22 +247,23 @@ func BenchmarkBufferedSub(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive the events
|
// Receive the events
|
||||||
done := make(chan struct{})
|
done := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(done)
|
|
||||||
recv := 0
|
recv := 0
|
||||||
var evs []Event
|
var evs []Event
|
||||||
for i := 0; i < b.N; {
|
for i := 0; i < b.N; {
|
||||||
evs = bs.Since(recv, evs[:0])
|
evs = bs.Since(recv, evs[:0])
|
||||||
for _, ev := range evs {
|
for _, ev := range evs {
|
||||||
if ev.GlobalID != recv+1 {
|
if ev.GlobalID != recv+1 {
|
||||||
b.Fatal("skipped event", ev.GlobalID, recv)
|
done <- fmt.Errorf("skipped event %v %v", ev.GlobalID, recv)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
recv = ev.GlobalID
|
recv = ev.GlobalID
|
||||||
coord <- struct{}{}
|
coord <- struct{}{}
|
||||||
}
|
}
|
||||||
i += len(evs)
|
i += len(evs)
|
||||||
}
|
}
|
||||||
|
done <- nil
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Send the events
|
// Send the events
|
||||||
|
@ -276,7 +277,9 @@ func BenchmarkBufferedSub(b *testing.B) {
|
||||||
<-coord
|
<-coord
|
||||||
}
|
}
|
||||||
|
|
||||||
<-done
|
if err := <-done; err != nil {
|
||||||
|
b.Error(err)
|
||||||
|
}
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ func TestCache(t *testing.T) {
|
||||||
c := newCache(nil)
|
c := newCache(nil)
|
||||||
|
|
||||||
res, ok := c.get("nonexistent")
|
res, ok := c.get("nonexistent")
|
||||||
if res.IsIgnored() || res.IsDeletable() || ok != false {
|
if res.IsIgnored() || res.IsDeletable() || ok {
|
||||||
t.Errorf("res %v, ok %v for nonexistent item", res, ok)
|
t.Errorf("res %v, ok %v for nonexistent item", res, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,12 @@ func TestCache(t *testing.T) {
|
||||||
c.set("false", 0)
|
c.set("false", 0)
|
||||||
|
|
||||||
res, ok = c.get("true")
|
res, ok = c.get("true")
|
||||||
if !res.IsIgnored() || !res.IsDeletable() || ok != true {
|
if !res.IsIgnored() || !res.IsDeletable() || !ok {
|
||||||
t.Errorf("res %v, ok %v for true item", res, ok)
|
t.Errorf("res %v, ok %v for true item", res, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, ok = c.get("false")
|
res, ok = c.get("false")
|
||||||
if res.IsIgnored() || res.IsDeletable() || ok != true {
|
if res.IsIgnored() || res.IsDeletable() || !ok {
|
||||||
t.Errorf("res %v, ok %v for false item", res, ok)
|
t.Errorf("res %v, ok %v for false item", res, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +41,12 @@ func TestCache(t *testing.T) {
|
||||||
// Same values should exist
|
// Same values should exist
|
||||||
|
|
||||||
res, ok = c.get("true")
|
res, ok = c.get("true")
|
||||||
if !res.IsIgnored() || !res.IsDeletable() || ok != true {
|
if !res.IsIgnored() || !res.IsDeletable() || !ok {
|
||||||
t.Errorf("res %v, ok %v for true item", res, ok)
|
t.Errorf("res %v, ok %v for true item", res, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, ok = c.get("false")
|
res, ok = c.get("false")
|
||||||
if res.IsIgnored() || res.IsDeletable() || ok != true {
|
if res.IsIgnored() || res.IsDeletable() || !ok {
|
||||||
t.Errorf("res %v, ok %v for false item", res, ok)
|
t.Errorf("res %v, ok %v for false item", res, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ func (d *deadlockDetector) Watch(name string, mut sync.Locker) {
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
mut.Lock()
|
mut.Lock()
|
||||||
|
_ = 1 // empty critical section
|
||||||
mut.Unlock()
|
mut.Unlock()
|
||||||
ok <- true
|
ok <- true
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -22,10 +22,7 @@ func SyncFile(path string) error {
|
||||||
}
|
}
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
// MacOS and Windows do not flush the disk cache
|
// MacOS and Windows do not flush the disk cache
|
||||||
if err := fd.Sync(); err != nil {
|
return fd.Sync()
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SyncDir(path string) error {
|
func SyncDir(path string) error {
|
||||||
|
|
|
@ -17,10 +17,10 @@ func (p *bufferPool) get(size int) []byte {
|
||||||
return p.new(size)
|
return p.new(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := intf.([]byte)
|
bs := *intf.(*[]byte)
|
||||||
if cap(bs) < size {
|
if cap(bs) < size {
|
||||||
// Buffer was too small, leave it for someone else and allocate.
|
// Buffer was too small, leave it for someone else and allocate.
|
||||||
p.put(bs)
|
p.pool.Put(intf)
|
||||||
return p.new(size)
|
return p.new(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ func (p *bufferPool) upgrade(bs []byte, size int) []byte {
|
||||||
|
|
||||||
// put returns the buffer to the pool
|
// put returns the buffer to the pool
|
||||||
func (p *bufferPool) put(bs []byte) {
|
func (p *bufferPool) put(bs []byte) {
|
||||||
p.pool.Put(bs)
|
p.pool.Put(&bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// new creates a new buffer of the requested size, taking the minimum
|
// new creates a new buffer of the requested size, taking the minimum
|
||||||
|
|
|
@ -105,11 +105,7 @@ func readHello(c io.Reader) (HelloResult, error) {
|
||||||
if err := hello.UnmarshalXDR(buf); err != nil {
|
if err := hello.UnmarshalXDR(buf); err != nil {
|
||||||
return HelloResult{}, err
|
return HelloResult{}, err
|
||||||
}
|
}
|
||||||
res := HelloResult{
|
res := HelloResult(hello)
|
||||||
DeviceName: hello.DeviceName,
|
|
||||||
ClientName: hello.ClientName,
|
|
||||||
ClientVersion: hello.ClientVersion,
|
|
||||||
}
|
|
||||||
return res, ErrTooOldVersion13
|
return res, ErrTooOldVersion13
|
||||||
|
|
||||||
case 0x00010001, 0x00010000:
|
case 0x00010001, 0x00010000:
|
||||||
|
|
|
@ -516,7 +516,7 @@ func (c *rawConnection) handleRequest(req Request) {
|
||||||
var done chan struct{}
|
var done chan struct{}
|
||||||
|
|
||||||
if usePool {
|
if usePool {
|
||||||
buf = c.pool.Get().([]byte)[:size]
|
buf = (*c.pool.Get().(*[]byte))[:size]
|
||||||
done = make(chan struct{})
|
done = make(chan struct{})
|
||||||
} else {
|
} else {
|
||||||
buf = make([]byte, size)
|
buf = make([]byte, size)
|
||||||
|
@ -539,7 +539,7 @@ func (c *rawConnection) handleRequest(req Request) {
|
||||||
|
|
||||||
if usePool {
|
if usePool {
|
||||||
<-done
|
<-done
|
||||||
c.pool.Put(buf)
|
c.pool.Put(&buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,11 +762,12 @@ func (c *rawConnection) close(err error) {
|
||||||
// results in an effecting ping interval of somewhere between
|
// results in an effecting ping interval of somewhere between
|
||||||
// PingSendInterval/2 and PingSendInterval.
|
// PingSendInterval/2 and PingSendInterval.
|
||||||
func (c *rawConnection) pingSender() {
|
func (c *rawConnection) pingSender() {
|
||||||
ticker := time.Tick(PingSendInterval / 2)
|
ticker := time.NewTicker(PingSendInterval / 2)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker:
|
case <-ticker.C:
|
||||||
d := time.Since(c.cw.Last())
|
d := time.Since(c.cw.Last())
|
||||||
if d < PingSendInterval/2 {
|
if d < PingSendInterval/2 {
|
||||||
l.Debugln(c.id, "ping skipped after wr", d)
|
l.Debugln(c.id, "ping skipped after wr", d)
|
||||||
|
@ -786,11 +787,12 @@ func (c *rawConnection) pingSender() {
|
||||||
// but we expect pings in the absence of other messages) within the last
|
// but we expect pings in the absence of other messages) within the last
|
||||||
// ReceiveTimeout. If not, we close the connection with an ErrTimeout.
|
// ReceiveTimeout. If not, we close the connection with an ErrTimeout.
|
||||||
func (c *rawConnection) pingReceiver() {
|
func (c *rawConnection) pingReceiver() {
|
||||||
ticker := time.Tick(ReceiveTimeout / 2)
|
ticker := time.NewTicker(ReceiveTimeout / 2)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker:
|
case <-ticker.C:
|
||||||
d := time.Since(c.cr.Last())
|
d := time.Since(c.cr.Last())
|
||||||
if d > ReceiveTimeout {
|
if d > ReceiveTimeout {
|
||||||
l.Debugln(c.id, "ping timeout", d)
|
l.Debugln(c.id, "ping timeout", d)
|
||||||
|
|
|
@ -80,7 +80,7 @@ func (h holder) String() string {
|
||||||
if h.at == "" {
|
if h.at == "" {
|
||||||
return "not held"
|
return "not held"
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("at %s goid: %d for %s", h.at, h.goid, time.Now().Sub(h.time))
|
return fmt.Sprintf("at %s goid: %d for %s", h.at, h.goid, time.Since(h.time))
|
||||||
}
|
}
|
||||||
|
|
||||||
type loggedMutex struct {
|
type loggedMutex struct {
|
||||||
|
@ -95,7 +95,7 @@ func (m *loggedMutex) Lock() {
|
||||||
|
|
||||||
func (m *loggedMutex) Unlock() {
|
func (m *loggedMutex) Unlock() {
|
||||||
currentHolder := m.holder.Load().(holder)
|
currentHolder := m.holder.Load().(holder)
|
||||||
duration := time.Now().Sub(currentHolder.time)
|
duration := time.Since(currentHolder.time)
|
||||||
if duration >= threshold {
|
if duration >= threshold {
|
||||||
l.Debugf("Mutex held for %v. Locked at %s unlocked at %s", duration, currentHolder.at, getHolder().at)
|
l.Debugf("Mutex held for %v. Locked at %s unlocked at %s", duration, currentHolder.at, getHolder().at)
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ func (m *loggedRWMutex) Lock() {
|
||||||
|
|
||||||
func (m *loggedRWMutex) Unlock() {
|
func (m *loggedRWMutex) Unlock() {
|
||||||
currentHolder := m.holder.Load().(holder)
|
currentHolder := m.holder.Load().(holder)
|
||||||
duration := time.Now().Sub(currentHolder.time)
|
duration := time.Since(currentHolder.time)
|
||||||
if duration >= threshold {
|
if duration >= threshold {
|
||||||
l.Debugf("RWMutex held for %v. Locked at %s unlocked at %s", duration, currentHolder.at, getHolder().at)
|
l.Debugf("RWMutex held for %v. Locked at %s unlocked at %s", duration, currentHolder.at, getHolder().at)
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ type loggedWaitGroup struct {
|
||||||
func (wg *loggedWaitGroup) Wait() {
|
func (wg *loggedWaitGroup) Wait() {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
wg.WaitGroup.Wait()
|
wg.WaitGroup.Wait()
|
||||||
duration := time.Now().Sub(start)
|
duration := time.Since(start)
|
||||||
if duration >= threshold {
|
if duration >= threshold {
|
||||||
l.Debugf("WaitGroup took %v at %s", duration, getHolder())
|
l.Debugf("WaitGroup took %v at %s", duration, getHolder())
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func TestSetDefaults(t *testing.T) {
|
||||||
t.Error("int failed")
|
t.Error("int failed")
|
||||||
} else if x.C != 0 {
|
} else if x.C != 0 {
|
||||||
t.Errorf("float failed")
|
t.Errorf("float failed")
|
||||||
} else if x.D != false {
|
} else if x.D {
|
||||||
t.Errorf("bool failed")
|
t.Errorf("bool failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ func TestSetDefaults(t *testing.T) {
|
||||||
t.Error("int failed")
|
t.Error("int failed")
|
||||||
} else if x.C != 2.2 {
|
} else if x.C != 2.2 {
|
||||||
t.Errorf("float failed")
|
t.Errorf("float failed")
|
||||||
} else if x.D != true {
|
} else if !x.D {
|
||||||
t.Errorf("bool failed")
|
t.Errorf("bool failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,11 +73,14 @@ func NewStaggered(folderID, folderPath string, params map[string]string) Version
|
||||||
l.Debugf("instantiated %#v", s)
|
l.Debugf("instantiated %#v", s)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
// TODO: This should be converted to a Serve() method.
|
||||||
s.clean()
|
s.clean()
|
||||||
if testCleanDone != nil {
|
if testCleanDone != nil {
|
||||||
close(testCleanDone)
|
close(testCleanDone)
|
||||||
}
|
}
|
||||||
for range time.Tick(time.Duration(cleanInterval) * time.Second) {
|
tck := time.NewTicker(time.Duration(cleanInterval) * time.Second)
|
||||||
|
defer tck.Stop()
|
||||||
|
for range tck.C {
|
||||||
s.clean()
|
s.clean()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -17,6 +17,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/lib/config"
|
"github.com/syncthing/syncthing/lib/config"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/rc"
|
"github.com/syncthing/syncthing/lib/rc"
|
||||||
|
|
Loading…
Reference in New Issue