github.com/letterj/go-ethereum@v1.8.22-0.20190204142846-520024dfd689/cmd/swarm/swarm-smoke/sliding_window.go (about) 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 17 package main 18 19 import ( 20 "crypto/md5" 21 crand "crypto/rand" 22 "fmt" 23 "io" 24 "math/rand" 25 "time" 26 27 "github.com/ethereum/go-ethereum/log" 28 "github.com/ethereum/go-ethereum/metrics" 29 "github.com/pborman/uuid" 30 31 cli "gopkg.in/urfave/cli.v1" 32 ) 33 34 var seed = time.Now().UTC().UnixNano() 35 36 func init() { 37 rand.Seed(seed) 38 } 39 40 type uploadResult struct { 41 hash string 42 digest []byte 43 } 44 45 func slidingWindow(c *cli.Context) error { 46 generateEndpoints(scheme, cluster, appName, from, to) 47 hashes := []uploadResult{} //swarm hashes of the uploads 48 nodes := to - from 49 const iterationTimeout = 30 * time.Second 50 log.Info("sliding window test started", "nodes", nodes, "filesize(kb)", filesize, "timeout", timeout) 51 uploadedBytes := 0 52 networkDepth := 0 53 errored := false 54 55 outer: 56 for { 57 log.Info("uploading to "+endpoints[0]+" and syncing", "seed", seed) 58 59 h := md5.New() 60 r := io.TeeReader(io.LimitReader(crand.Reader, int64(filesize*1000)), h) 61 t1 := time.Now() 62 63 hash, err := upload(r, filesize*1000, endpoints[0]) 64 if err != nil { 65 log.Error(err.Error()) 66 return err 67 } 68 69 metrics.GetOrRegisterResettingTimer("sliding-window.upload-time", nil).UpdateSince(t1) 70 71 fhash := h.Sum(nil) 72 73 log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash), "sleeping", syncDelay) 74 hashes = append(hashes, uploadResult{hash: hash, digest: fhash}) 75 time.Sleep(time.Duration(syncDelay) * time.Second) 76 uploadedBytes += filesize * 1000 77 78 for i, v := range hashes { 79 timeout := time.After(time.Duration(timeout) * time.Second) 80 errored = false 81 82 inner: 83 for { 84 select { 85 case <-timeout: 86 errored = true 87 log.Error("error retrieving hash. timeout", "hash idx", i, "err", err) 88 metrics.GetOrRegisterCounter("sliding-window.single.error", nil).Inc(1) 89 break inner 90 default: 91 randIndex := 1 + rand.Intn(len(endpoints)-1) 92 ruid := uuid.New()[:8] 93 start := time.Now() 94 err := fetch(v.hash, endpoints[randIndex], v.digest, ruid) 95 if err != nil { 96 continue inner 97 } 98 metrics.GetOrRegisterResettingTimer("sliding-window.single.fetch-time", nil).UpdateSince(start) 99 break inner 100 } 101 } 102 103 if errored { 104 break outer 105 } 106 networkDepth = i 107 metrics.GetOrRegisterGauge("sliding-window.network-depth", nil).Update(int64(networkDepth)) 108 } 109 } 110 111 log.Info("sliding window test finished", "errored?", errored, "networkDepth", networkDepth, "networkDepth(kb)", networkDepth*filesize) 112 log.Info("stats", "uploadedFiles", len(hashes), "uploadedKb", uploadedBytes/1000, "filesizeKb", filesize) 113 114 return nil 115 }