todoService.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package main
  2. import (
  3. "log"
  4. "sort"
  5. "sync"
  6. "github.com/cryptix/exp/humbleRpcTodo/types"
  7. "gopkg.in/errgo.v1"
  8. )
  9. var (
  10. // todosMutex protects access to the todos map
  11. todosMutex = sync.Mutex{}
  12. // todos stores all the todos as a map of id to *Todo
  13. todos = make(types.TodosIndex, 10)
  14. // todosCounter is incremented every time a new todo is created
  15. // it is used to set todo ids.
  16. todosCounter = 1
  17. )
  18. func init() {
  19. createTodo("Write a frontend framework in Go")
  20. createTodo("???")
  21. createTodo("Profit!")
  22. }
  23. func createTodo(title string) *types.Todo {
  24. todosMutex.Lock()
  25. defer todosMutex.Unlock()
  26. id := todosCounter
  27. todosCounter++
  28. todo := &types.Todo{
  29. Id: id,
  30. Title: title,
  31. }
  32. todos[id] = todo
  33. return todo
  34. }
  35. var ErrTodoNotFound = errgo.New("todo not found")
  36. // Todos RPC
  37. type TodoService struct{}
  38. func (*TodoService) List(args *types.TodoListArgs, reply *[]types.Todo) error {
  39. todoList := make([]types.Todo, len(todos))
  40. i := 0
  41. for _, v := range todos {
  42. todoList[i] = *v
  43. i++
  44. }
  45. sort.Sort(types.ById(todoList))
  46. *reply = todoList
  47. log.Printf("Listed %+v", reply)
  48. return nil
  49. }
  50. func (*TodoService) Save(in *types.Todo, out *types.Todo) error {
  51. if in == nil || in.Title == "" {
  52. return errgo.New("no title")
  53. }
  54. // create
  55. if in.Id == 0 {
  56. newTodo := createTodo(in.Title)
  57. log.Printf("Created %+v", newTodo)
  58. *out = *newTodo
  59. return nil
  60. }
  61. // save
  62. todosMutex.Lock()
  63. defer todosMutex.Unlock()
  64. if _, found := todos[in.Id]; !found {
  65. return ErrTodoNotFound
  66. }
  67. todos[in.Id] = in
  68. *out = *in
  69. log.Printf("Saved %+v", out)
  70. return nil
  71. }
  72. func (*TodoService) Delete(id *int, _ *struct{}) error {
  73. if id == nil {
  74. return errgo.New("invalid id")
  75. }
  76. todosMutex.Lock()
  77. defer todosMutex.Unlock()
  78. if _, ok := todos[*id]; !ok {
  79. return ErrTodoNotFound
  80. }
  81. // Delete the todo and render a response
  82. delete(todos, *id)
  83. log.Printf("Deleted %d", *id)
  84. return nil
  85. }