stresser.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. } else {
  59. s.success++
  60. }
  61. s.mu.Unlock()
  62. }
  63. }()
  64. }
  65. <-ctx.Done()
  66. return nil
  67. }
  68. func (s *stresser) Cancel() {
  69. s.cancel()
  70. }
  71. func (s *stresser) Report() (success int, failure int) {
  72. s.mu.Lock()
  73. defer s.mu.Unlock()
  74. return s.success, s.failure
  75. }