background.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package worker
  2. import (
  3. "fmt"
  4. "time"
  5. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/dao"
  6. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/model"
  7. )
  8. const SystemBackend = "_system"
  9. const TaskModelName = "tasks"
  10. var lastChecked time.Time
  11. var backgroundConfig BackgroundConfig
  12. //BackgroundConfig configuration of background tasks
  13. type BackgroundConfig struct {
  14. Period int
  15. DeleteOrphanedFiles bool
  16. }
  17. //InitBackgroundTasks initialise background tasks
  18. func InitBackgroundTasks(config BackgroundConfig) {
  19. backgroundConfig = config
  20. period := config.Period
  21. log.Infof("healthcheck starting with period: %d seconds", period)
  22. if period > 0 {
  23. go func() {
  24. background := time.NewTicker(time.Second * time.Duration(period))
  25. for range background.C {
  26. doTask()
  27. }
  28. }()
  29. }
  30. }
  31. func GetTaskRoute() model.Route {
  32. return model.Route{
  33. Backend: SystemBackend,
  34. Model: TaskModelName,
  35. }
  36. }
  37. //doTask internal function to process the background tasks
  38. func doTask() {
  39. storage := dao.GetStorage()
  40. // prepare the backend models, getting all models and backends with file fields
  41. fileBackends := make([]map[string]string, 0)
  42. for _, k := range model.BackendList.Names() {
  43. backend, _ := model.BackendList.Get(k)
  44. for _, m := range backend.Models {
  45. for _, f := range m.Fields {
  46. if f.Type == model.FieldTypeFile {
  47. info := make(map[string]string)
  48. info["backend"] = k
  49. info["model"] = m.Name
  50. info["field"] = f.Name
  51. fileBackends = append(fileBackends, info)
  52. }
  53. }
  54. }
  55. }
  56. storage.ProcessFiles(func(info model.FileInfo) bool {
  57. if info.UploadDate.Add(1 * time.Hour).After(time.Now()) {
  58. return false
  59. }
  60. toDelete := true
  61. // log.Infof("found file: %s, id: %s, backend: %s", info.Filename, info.ID, info.Backend)
  62. // get the right backend
  63. for _, fileBackend := range fileBackends {
  64. if info.Backend == fileBackend["backend"] {
  65. route := model.Route{
  66. Backend: info.Backend,
  67. Model: fileBackend["model"],
  68. }
  69. query := fmt.Sprintf("{ \"%s\": \"%s\"}", fileBackend["field"], info.ID)
  70. count, _, _ := storage.QueryModel(route, query, 0, 0)
  71. if count > 0 {
  72. toDelete = false
  73. }
  74. }
  75. }
  76. log.Infof("file has to be deleted: %s", toDelete)
  77. if toDelete && backgroundConfig.DeleteOrphanedFiles {
  78. storage.DeleteFile(info.Backend, info.ID)
  79. }
  80. return toDelete
  81. })
  82. lastChecked = time.Now()
  83. }
  84. func reportOrphanedFiles() {
  85. storage := dao.GetStorage()
  86. taskRoute := GetTaskRoute()
  87. task := model.Task{
  88. Type: model.TaskOrphanedFilesReport,
  89. Status: model.New,
  90. }
  91. task, err := createTask(taskRoute, task)
  92. if err != nil {
  93. log.Alertf("error creating task: %v", err)
  94. return
  95. }
  96. files := make([]model.FileInfo, 0)
  97. // prepare the backend models, getting all models and backends with file fields
  98. fileBackends := make([]map[string]string, 0)
  99. for _, k := range model.BackendList.Names() {
  100. backend, _ := model.BackendList.Get(k)
  101. for _, m := range backend.Models {
  102. for _, f := range m.Fields {
  103. if f.Type == model.FieldTypeFile {
  104. info := make(map[string]string)
  105. info["backend"] = k
  106. info["model"] = m.Name
  107. info["field"] = f.Name
  108. fileBackends = append(fileBackends, info)
  109. }
  110. }
  111. }
  112. }
  113. task.Status = model.Running
  114. updateTask(taskRoute, task)
  115. err = storage.ProcessFiles(func(info model.FileInfo) bool {
  116. if info.UploadDate.Add(1 * time.Hour).After(time.Now()) {
  117. return false
  118. }
  119. toDelete := true
  120. // log.Infof("found file: %s, id: %s, backend: %s", info.Filename, info.ID, info.Backend)
  121. // get the right backend
  122. for _, fileBackend := range fileBackends {
  123. if info.Backend == fileBackend["backend"] {
  124. route := model.Route{
  125. Backend: info.Backend,
  126. Model: fileBackend["model"],
  127. }
  128. query := fmt.Sprintf("{ \"%s\": \"%s\"}", fileBackend["field"], info.ID)
  129. count, _, _ := storage.QueryModel(route, query, 0, 0)
  130. if count > 0 {
  131. toDelete = false
  132. }
  133. }
  134. }
  135. log.Infof("file has to be deleted: %s", toDelete)
  136. if toDelete {
  137. files = append(files, info)
  138. }
  139. return toDelete
  140. })
  141. if err != nil {
  142. log.Alertf("error: %s\n", err.Error())
  143. return
  144. }
  145. task.Data = model.JSONMap{}
  146. task.Data["fileids"] = files
  147. task.Status = model.Finished
  148. updateTask(taskRoute, task)
  149. }
  150. func updateTask(taskRoute model.Route, task model.Task) {
  151. taskRoute.Identity = task.ID
  152. jsonMap, err := task.ToJSONMap()
  153. if err != nil {
  154. return
  155. }
  156. _, err = dao.GetStorage().UpdateModel(taskRoute, jsonMap)
  157. if err != nil {
  158. log.Alertf("error updating task: %v", err)
  159. return
  160. }
  161. }
  162. func createTask(taskRoute model.Route, task model.Task) (model.Task, error) {
  163. jsonMap, err := task.ToJSONMap()
  164. if err != nil {
  165. return model.Task{}, err
  166. }
  167. id, err := dao.GetStorage().CreateModel(taskRoute, jsonMap)
  168. if err != nil {
  169. log.Alertf("error creating task: %v", err)
  170. return model.Task{}, err
  171. }
  172. task.ID = id
  173. return task, nil
  174. }