Start.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package client
  2. import (
  3. "log"
  4. "net/url"
  5. "os"
  6. "os/signal"
  7. "strconv"
  8. "time"
  9. "github.com/gorilla/websocket"
  10. "github.com/inhies/go-bytesize"
  11. "github.com/mackerelio/go-osstat/memory"
  12. "github.com/shirou/gopsutil/v4/cpu"
  13. )
  14. func (client *Client) Start() {
  15. // Setup the interrupts
  16. interrupt := make(chan os.Signal, 1)
  17. signal.Notify(interrupt, os.Interrupt)
  18. u := url.URL{Scheme: "ws", Host: client.ServerAddress + ":" + strconv.Itoa(client.ServerPort), Path: "/ws"}
  19. log.Printf("Connecting to %s", u.String())
  20. // sigh
  21. var err error
  22. client.conn, _, err = websocket.DefaultDialer.Dial(u.String(), nil)
  23. if err != nil {
  24. log.Fatal("dial:", err)
  25. }
  26. defer client.conn.Close()
  27. done := make(chan struct{})
  28. // Setup updater logic
  29. updater := make(chan string)
  30. go client.statusUpdater(updater)
  31. go func() {
  32. defer close(done)
  33. for {
  34. _, message, err := client.conn.ReadMessage()
  35. if err != nil {
  36. log.Println("read:", err)
  37. return
  38. }
  39. log.Printf("recv: %s", message)
  40. }
  41. }()
  42. for {
  43. select {
  44. case <-done:
  45. return
  46. case update := <-updater: // Dumping this into a var saves a second. Weird!
  47. // Dump the message towards the server.
  48. err = client.conn.WriteMessage(websocket.TextMessage, []byte(update))
  49. if err != nil {
  50. log.Println("write:", err)
  51. return
  52. }
  53. case <-interrupt:
  54. log.Println("interrupt")
  55. // Cleanly close the connection by sending a close message and then
  56. // waiting (with timeout) for the server to close the connection.
  57. err := client.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
  58. if err != nil {
  59. log.Println("write close:", err)
  60. return
  61. }
  62. select {
  63. case <-done:
  64. case <-time.After(time.Second):
  65. }
  66. return
  67. }
  68. }
  69. }
  70. func (client *Client) statusUpdater(updater chan string) {
  71. for {
  72. // Fetch CPU usage in percentages
  73. cpustats, err := cpu.Percent(time.Second, false)
  74. if err != nil {
  75. log.Println("Err:", err)
  76. }
  77. // Fetch memory stats in bytes
  78. mem, err := memory.Get()
  79. if err != nil {
  80. log.Println("Err:", err)
  81. }
  82. // Use the ByteSize package to allow for memory calculations
  83. b := bytesize.New(float64(mem.Used))
  84. // Dump the message towards the server.
  85. updater <- "update;" + strconv.Itoa(int(cpustats[0])) + ";" + b.String() + ";" + strconv.Itoa(client.taskId)
  86. }
  87. }