You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
2.2 KiB

  1. package utils
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "runtime"
  8. "sync"
  9. )
  10. type RunTask interface {
  11. AddTask()
  12. RunTask()
  13. }
  14. // T: Task任务
  15. type T struct {
  16. sync.Mutex
  17. // ch: 获取事件channel
  18. ch chan struct{}
  19. closeChan chan struct{}
  20. // 记录process对象
  21. p *os.Process
  22. // f: 执行任务
  23. f func(chan struct{}) error
  24. }
  25. // NewT: 实例化方法
  26. func NewT() *T {
  27. return newT(nil)
  28. }
  29. func newT(f func(chan struct{}) error) *T {
  30. t := &T{
  31. Mutex: sync.Mutex{},
  32. ch: make(chan struct{}, 1),
  33. closeChan: make(chan struct{}),
  34. f: f,
  35. }
  36. if f == nil {
  37. t.f = t.DefaultF
  38. }
  39. return t
  40. }
  41. func (t *T) AddTask() {
  42. t.Lock()
  43. defer t.Unlock()
  44. if len(t.ch) == 1 {
  45. // 代表已经有任务了
  46. // 直接丢弃这次任务
  47. return
  48. }
  49. t.ch <- struct{}{}
  50. }
  51. func (t *T) RunTask() {
  52. fmt.Println("进入")
  53. // 这里做的make 是用于关闭上一个执行的任务
  54. ch := make(chan struct{})
  55. // 先run服务
  56. go t.f(ch)
  57. for {
  58. _, ok := <-t.ch
  59. ch <- struct{}{}
  60. if !ok {
  61. return
  62. }
  63. // 等待上一个关闭
  64. <-t.closeChan
  65. go t.f(ch)
  66. }
  67. }
  68. // DefaultF: 默认的StartFunction
  69. func (t *T) DefaultF(ch chan struct{}) error {
  70. var buildCmd *exec.Cmd
  71. var cmd *exec.Cmd
  72. // 判断是否有makefile
  73. _, err := os.Stat(filepath.Join("Makefile"))
  74. if runtime.GOOS != "windows" && err != nil {
  75. _, err := exec.LookPath("make")
  76. if err == nil {
  77. cmd = exec.Command("makefile")
  78. goto makefile
  79. }
  80. }
  81. // 检测系统是否有编译环境
  82. _, err = exec.LookPath("go")
  83. if err != nil {
  84. return err
  85. }
  86. // build
  87. switch runtime.GOOS {
  88. case "windows":
  89. buildCmd = exec.Command("go", "build", "-o", "gva.exe", "main.go")
  90. default:
  91. buildCmd = exec.Command("go", "build", "-o", "gva", "main.go")
  92. }
  93. err = buildCmd.Run()
  94. fmt.Println("build 执行完成")
  95. if err != nil {
  96. return err
  97. }
  98. // 执行
  99. switch runtime.GOOS {
  100. case "windows":
  101. cmd = exec.Command("gva.exe")
  102. default:
  103. cmd = exec.Command("./gva")
  104. }
  105. makefile:
  106. // 开始执行任务
  107. err = cmd.Start()
  108. if err != nil {
  109. return err
  110. }
  111. t.p = cmd.Process
  112. fmt.Println("pid", t.p.Pid)
  113. go func() {
  114. err = cmd.Wait()
  115. }()
  116. <-ch
  117. // 回收资源
  118. err = cmd.Process.Kill()
  119. fmt.Println("kill err", err)
  120. // 发送关闭完成信号
  121. t.closeChan <- struct{}{}
  122. return err
  123. }