stresser.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package main
  2. import (
  3. "net"
  4. "net/http"
  5. "sync"
  6. "time"
  7. "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
  8. "github.com/coreos/etcd/client"
  9. )
  10. type Stresser interface {
  11. // Stress starts to stress the etcd cluster
  12. Stress() error
  13. // Cancel cancels the stress test on the etcd cluster
  14. Cancel()
  15. // Report reports the success and failure of the stress test
  16. Report() (success int, failure int)
  17. }
  18. type stresser struct {
  19. Endpoint string
  20. // TODO: not implemented
  21. SuffixRange int
  22. N int
  23. // TODO: not implemented
  24. Interval time.Duration
  25. mu sync.Mutex
  26. failure int
  27. success int
  28. cancel func()
  29. }
  30. func (s *stresser) Stress() error {
  31. cfg := client.Config{
  32. Endpoints: []string{s.Endpoint},
  33. Transport: &http.Transport{
  34. Dial: (&net.Dialer{
  35. Timeout: time.Second,
  36. KeepAlive: 30 * time.Second,
  37. }).Dial,
  38. MaxIdleConnsPerHost: s.N,
  39. },
  40. }
  41. c, err := client.New(cfg)
  42. if err != nil {
  43. return err
  44. }
  45. kv := client.NewKeysAPI(c)
  46. ctx, cancel := context.WithCancel(context.Background())
  47. s.cancel = cancel
  48. for i := 0; i < s.N; i++ {
  49. go func() {
  50. for {
  51. _, err := kv.Set(ctx, "foo", "bar", nil)
  52. if err == context.Canceled {
  53. return
  54. }
  55. s.mu.Lock()
  56. if err != nil {
  57. s.failure++
  58. }
  59. s.success++
  60. s.mu.Unlock()
  61. }
  62. }()
  63. }
  64. <-ctx.Done()
  65. return nil
  66. }
  67. func (s *stresser) Cancel() {
  68. s.cancel()
  69. }
  70. func (s *stresser) Report() (success int, failure int) {
  71. s.mu.Lock()
  72. defer s.mu.Unlock()
  73. return s.success, s.failure
  74. }