sliding_window.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright 2018 The go-ethereum Authors
  2. // This file is part of go-ethereum.
  3. //
  4. // go-ethereum is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // go-ethereum is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  16. package main
  17. import (
  18. "bytes"
  19. "fmt"
  20. "math/rand"
  21. "time"
  22. "github.com/ethereum/go-ethereum/log"
  23. "github.com/ethereum/go-ethereum/metrics"
  24. "github.com/ethereum/go-ethereum/swarm/testutil"
  25. "github.com/pborman/uuid"
  26. cli "gopkg.in/urfave/cli.v1"
  27. )
  28. type uploadResult struct {
  29. hash string
  30. digest []byte
  31. }
  32. func slidingWindowCmd(ctx *cli.Context, tuid string) error {
  33. errc := make(chan error)
  34. go func() {
  35. errc <- slidingWindow(ctx, tuid)
  36. }()
  37. select {
  38. case err := <-errc:
  39. if err != nil {
  40. metrics.GetOrRegisterCounter(fmt.Sprintf("%s.fail", commandName), nil).Inc(1)
  41. }
  42. return err
  43. case <-time.After(time.Duration(timeout) * time.Second):
  44. metrics.GetOrRegisterCounter(fmt.Sprintf("%s.timeout", commandName), nil).Inc(1)
  45. return fmt.Errorf("timeout after %v sec", timeout)
  46. }
  47. }
  48. func slidingWindow(ctx *cli.Context, tuid string) error {
  49. var hashes []uploadResult //swarm hashes of the uploads
  50. nodes := len(hosts)
  51. const iterationTimeout = 30 * time.Second
  52. log.Info("sliding window test started", "tuid", tuid, "nodes", nodes, "filesize(kb)", filesize, "timeout", timeout)
  53. uploadedBytes := 0
  54. networkDepth := 0
  55. errored := false
  56. outer:
  57. for {
  58. log.Info("uploading to "+httpEndpoint(hosts[0])+" and syncing", "seed", seed)
  59. t1 := time.Now()
  60. randomBytes := testutil.RandomBytes(seed, filesize*1000)
  61. hash, err := upload(randomBytes, httpEndpoint(hosts[0]))
  62. if err != nil {
  63. log.Error(err.Error())
  64. return err
  65. }
  66. metrics.GetOrRegisterResettingTimer("sliding-window.upload-time", nil).UpdateSince(t1)
  67. fhash, err := digest(bytes.NewReader(randomBytes))
  68. if err != nil {
  69. log.Error(err.Error())
  70. return err
  71. }
  72. log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash), "sleeping", syncDelay)
  73. hashes = append(hashes, uploadResult{hash: hash, digest: fhash})
  74. time.Sleep(time.Duration(syncDelay) * time.Second)
  75. uploadedBytes += filesize * 1000
  76. for i, v := range hashes {
  77. timeout := time.After(time.Duration(timeout) * time.Second)
  78. errored = false
  79. inner:
  80. for {
  81. select {
  82. case <-timeout:
  83. errored = true
  84. log.Error("error retrieving hash. timeout", "hash idx", i, "err", err)
  85. metrics.GetOrRegisterCounter("sliding-window.single.error", nil).Inc(1)
  86. break inner
  87. default:
  88. idx := 1 + rand.Intn(len(hosts)-1)
  89. ruid := uuid.New()[:8]
  90. start := time.Now()
  91. err := fetch(v.hash, httpEndpoint(hosts[idx]), v.digest, ruid, "")
  92. if err != nil {
  93. continue inner
  94. }
  95. metrics.GetOrRegisterResettingTimer("sliding-window.single.fetch-time", nil).UpdateSince(start)
  96. break inner
  97. }
  98. }
  99. if errored {
  100. break outer
  101. }
  102. networkDepth = i
  103. metrics.GetOrRegisterGauge("sliding-window.network-depth", nil).Update(int64(networkDepth))
  104. }
  105. }
  106. log.Info("sliding window test finished", "errored?", errored, "networkDepth", networkDepth, "networkDepth(kb)", networkDepth*filesize)
  107. log.Info("stats", "uploadedFiles", len(hashes), "uploadedKb", uploadedBytes/1000, "filesizeKb", filesize)
  108. return nil
  109. }