diff --git a/bench/consume.go b/bench/consume.go new file mode 100644 index 0000000000000000000000000000000000000000..195c232fcb1bbe934b3a561f5b5ab3a4bfd84128 --- /dev/null +++ b/bench/consume.go @@ -0,0 +1,32 @@ +package main + +import ( + "io/ioutil" + "net/http" + "net/url" + "time" +) + +func Consume(add string, interv int, run *bool) error { + u, e := url.Parse(add) + if e != nil { + return e + } + u.Path = "/out/" + + t := time.NewTicker(time.Millisecond * time.Duration(interv)) + + for *run { + _ = <-t.C + resp, e := http.Get(u.String()) + if e != nil { + return e + } + _, e = ioutil.ReadAll(resp.Body) + if e != nil { + return e + } + } + + return nil +} diff --git a/bench/main.go b/bench/main.go new file mode 100644 index 0000000000000000000000000000000000000000..cc37737ddd67ac504aaf96f9e451c4cb9a7f7cc2 --- /dev/null +++ b/bench/main.go @@ -0,0 +1,85 @@ +package main + +import ( + "flag" + "fmt" + "math/rand" + "strings" + "time" +) + +type stringSlice []string + +func (s *stringSlice) String() string { + return strings.Join(*s, " ") +} + +func (s *stringSlice) Set(value string) error { + *s = append(*s, value) + return nil +} + +func (s *stringSlice) RandElement() string { + l := len(*s) + if l == 0 { + return "" + } + n := rand.Intn(l) + return (*s)[n] +} + +var ( + loc = flag.String("locations", "http://localhost:8080", "location of server") + prod = flag.Int("producers", 100, "number of producers") + cons = flag.Int("consumers", 1, "number of consumers") + prodInt = flag.Int("prod-interval", 1000, "interval of clicks in ms") + consInt = flag.Int("cons-interval", 1000, "interval of loads in ms") + teams, choices stringSlice +) + +func init() { + flag.Var(&teams, "team", "add team") + flag.Var(&choices, "choice", "add choice") +} + +func main() { + flag.Parse() + + run := true + proderr := make(chan error) + conserr := make(chan error) + + prodSleep := time.Duration(float64(*prodInt) / float64(*prod)) + for i := 0; i < *prod; i++ { + go func() { + proderr <- Produce(*loc, *prodInt, &run, teams, choices) + }() + time.Sleep(prodSleep) + } + + consSleep := time.Duration(float64(*consInt) / float64(*cons)) + for i := 0; i < *cons; i++ { + go func() { + conserr <- Consume(*loc, *consInt, &run) + }() + time.Sleep(consSleep) + } + + fmt.Println("started benchmark") + fmt.Println("voters:", *prod) + fmt.Println("voting interval:", *prodInt) + fmt.Println("consumers:", *cons) + fmt.Println("consumer interval:", *consInt) + fmt.Println("teams:", teams.String()) + fmt.Println("choices:", choices.String()) + + for { + select { + case err := <-conserr: + fmt.Println("consumer error:", err) + case err := <-proderr: + fmt.Println("producer error:", err) + } + } + +} diff --git a/bench/produce.go b/bench/produce.go new file mode 100644 index 0000000000000000000000000000000000000000..be5f982d7afdf6aa548a6b7a1f4f71f0cf08a91a --- /dev/null +++ b/bench/produce.go @@ -0,0 +1,53 @@ +package main + +import ( + "github.com/gorilla/websocket" + "net/url" + "time" +) + +func Produce(add string, interv int, run *bool, teams, choices stringSlice) error { + u, e := url.Parse(add) + if e != nil { + return e + } + u.Scheme = "ws" + u.Path = "/in/websocket" + + c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) + if err != nil { + return err + } + + d := make(chan error) + + go func() { + for { + _, _, err := c.ReadMessage() + if err != nil { + d <- err + return + } + } + }() + + err = c.WriteMessage(websocket.TextMessage, []byte(teams.RandElement())) + if err != nil { + return err + } + + ticker := time.NewTicker(time.Millisecond * time.Duration(interv)) + + go func() { + for *run { + _ = <-ticker.C + e := c.WriteMessage(websocket.TextMessage, []byte(choices.RandElement())) + if e != nil { + d <- e + return + } + } + }() + + return <-d +} diff --git a/docker-compose.yml b/docker-compose.yml index dd8527a29e75abeda5f97c9c9f1c80b015c17d22..345188956c5469644d82333e0cacbcf466124c5d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,8 @@ services: - POSTGRES_PASSWORD=matrix - POSTGRES_USER=matrix - POSTGRES_DB=matrix + volumes: + - postgres:/var/lib/postgresql/data volumes: postgres: \ No newline at end of file diff --git a/go.mod b/go.mod index b5087038551f20651e329e468a69241918d46cf0..fb3658fc9f1688573622354d5f96589030d10664 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ go 1.15 require ( github.com/go-pg/pg/v10 v10.7.5 + github.com/gorilla/websocket v1.4.2 github.com/igm/sockjs-go/v3 v3.0.0 github.com/prometheus/client_golang v1.9.0 gitlab.com/MikeTTh/env v0.0.0-20210102155928-2e9be3823cc7