command.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package main
  2. //------------------------------------------------------------------------------
  3. //
  4. // Commands
  5. //
  6. //------------------------------------------------------------------------------
  7. import (
  8. "encoding/json"
  9. "github.com/xiangli-cmu/go-raft"
  10. "github.com/xiangli-cmu/raft-etcd/store"
  11. "time"
  12. )
  13. // A command represents an action to be taken on the replicated state machine.
  14. type Command interface {
  15. CommandName() string
  16. Apply(server *raft.Server) (interface{}, error)
  17. }
  18. // Set command
  19. type SetCommand struct {
  20. Key string `json:"key"`
  21. Value string `json:"value"`
  22. ExpireTime time.Time `json:"expireTime"`
  23. }
  24. // The name of the command in the log
  25. func (c *SetCommand) CommandName() string {
  26. return "set"
  27. }
  28. // Set the value of key to value
  29. func (c *SetCommand) Apply(server *raft.Server) (interface{}, error) {
  30. return store.Set(c.Key, c.Value, c.ExpireTime, server.CommittedIndex())
  31. }
  32. // Get the path for http request
  33. func (c *SetCommand) GeneratePath() string {
  34. return "set/" + c.Key
  35. }
  36. // Get command
  37. type GetCommand struct {
  38. Key string `json:"key"`
  39. }
  40. // The name of the command in the log
  41. func (c *GetCommand) CommandName() string {
  42. return "get"
  43. }
  44. // Set the value of key to value
  45. func (c *GetCommand) Apply(server *raft.Server) (interface{}, error) {
  46. res := store.Get(c.Key)
  47. return json.Marshal(res)
  48. }
  49. func (c *GetCommand) GeneratePath() string {
  50. return "get/" + c.Key
  51. }
  52. // List command
  53. type ListCommand struct {
  54. Prefix string `json:"prefix"`
  55. }
  56. // The name of the command in the log
  57. func (c *ListCommand) CommandName() string {
  58. return "list"
  59. }
  60. // Set the value of key to value
  61. func (c *ListCommand) Apply(server *raft.Server) (interface{}, error) {
  62. return store.List(c.Prefix)
  63. }
  64. // Delete command
  65. type DeleteCommand struct {
  66. Key string `json:"key"`
  67. }
  68. // The name of the command in the log
  69. func (c *DeleteCommand) CommandName() string {
  70. return "delete"
  71. }
  72. // Delete the key
  73. func (c *DeleteCommand) Apply(server *raft.Server) (interface{}, error) {
  74. return store.Delete(c.Key, server.CommittedIndex())
  75. }
  76. // Watch command
  77. type WatchCommand struct {
  78. Key string `json:"key"`
  79. SinceIndex uint64 `json:"sinceIndex"`
  80. }
  81. //The name of the command in the log
  82. func (c *WatchCommand) CommandName() string {
  83. return "watch"
  84. }
  85. func (c *WatchCommand) Apply(server *raft.Server) (interface{}, error) {
  86. ch := make(chan store.Response, 1)
  87. // add to the watchers list
  88. store.AddWatcher(c.Key, ch, c.SinceIndex)
  89. // wait for the notification for any changing
  90. res := <-ch
  91. return json.Marshal(res)
  92. }
  93. // JoinCommand
  94. type JoinCommand struct {
  95. Name string `json:"name"`
  96. }
  97. func (c *JoinCommand) CommandName() string {
  98. return "join"
  99. }
  100. func (c *JoinCommand) Apply(server *raft.Server) (interface{}, error) {
  101. err := server.AddPeer(c.Name)
  102. // no result will be returned
  103. return nil, err
  104. }