25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

135 lines
3.0 KiB

  1. // Copyright 2017 The Go Authors. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style
  4. // license that can be found in the LICENSE file or at
  5. // https://developers.google.com/open-source/licenses/bsd.
  6. package main
  7. import (
  8. "log"
  9. "time"
  10. "github.com/spf13/viper"
  11. "google.golang.org/appengine"
  12. "github.com/golang/gddo/database"
  13. "github.com/golang/gddo/gosrc"
  14. )
  15. type BackgroundTask struct {
  16. name string
  17. fn func() error
  18. interval time.Duration
  19. next time.Time
  20. }
  21. func runBackgroundTasks() {
  22. defer log.Println("ERROR: Background exiting!")
  23. var backgroundTasks = []BackgroundTask{
  24. {
  25. name: "GitHub updates",
  26. fn: readGitHubUpdates,
  27. interval: viper.GetDuration(ConfigGithubInterval),
  28. },
  29. {
  30. name: "Crawl",
  31. fn: doCrawl,
  32. interval: viper.GetDuration(ConfigCrawlInterval),
  33. },
  34. }
  35. sleep := time.Minute
  36. for _, task := range backgroundTasks {
  37. if task.interval > 0 && sleep > task.interval {
  38. sleep = task.interval
  39. }
  40. }
  41. for {
  42. for _, task := range backgroundTasks {
  43. start := time.Now()
  44. if task.interval > 0 && start.After(task.next) {
  45. if err := task.fn(); err != nil {
  46. log.Printf("Task %s: %v", task.name, err)
  47. }
  48. task.next = time.Now().Add(task.interval)
  49. }
  50. }
  51. time.Sleep(sleep)
  52. }
  53. }
  54. func doCrawl() error {
  55. // Look for new package to crawl.
  56. importPath, hasSubdirs, err := db.PopNewCrawl()
  57. if err != nil {
  58. log.Printf("db.PopNewCrawl() returned error %v", err)
  59. return nil
  60. }
  61. if importPath != "" {
  62. if pdoc, err := crawlDoc("new", importPath, nil, hasSubdirs, time.Time{}); pdoc == nil && err == nil {
  63. if err := db.AddBadCrawl(importPath); err != nil {
  64. log.Printf("ERROR db.AddBadCrawl(%q): %v", importPath, err)
  65. }
  66. }
  67. return nil
  68. }
  69. // Crawl existing doc.
  70. pdoc, pkgs, nextCrawl, err := db.Get("-")
  71. if err != nil {
  72. log.Printf("db.Get(\"-\") returned error %v", err)
  73. return nil
  74. }
  75. if pdoc == nil || nextCrawl.After(time.Now()) {
  76. return nil
  77. }
  78. if _, err = crawlDoc("crawl", pdoc.ImportPath, pdoc, len(pkgs) > 0, nextCrawl); err != nil {
  79. // Touch package so that crawl advances to next package.
  80. if err := db.SetNextCrawl(pdoc.ImportPath, time.Now().Add(viper.GetDuration(ConfigMaxAge)/3)); err != nil {
  81. log.Printf("ERROR db.SetNextCrawl(%q): %v", pdoc.ImportPath, err)
  82. }
  83. }
  84. return nil
  85. }
  86. func readGitHubUpdates() error {
  87. const key = "gitHubUpdates"
  88. var last string
  89. if err := db.GetGob(key, &last); err != nil {
  90. return err
  91. }
  92. last, names, err := gosrc.GetGitHubUpdates(httpClient, last)
  93. if err != nil {
  94. return err
  95. }
  96. for _, name := range names {
  97. log.Printf("bump crawl github.com/%s", name)
  98. if err := db.BumpCrawl("github.com/" + name); err != nil {
  99. log.Println("ERROR force crawl:", err)
  100. }
  101. }
  102. if err := db.PutGob(key, last); err != nil {
  103. return err
  104. }
  105. return nil
  106. }
  107. func reindex() {
  108. c := appengine.BackgroundContext()
  109. if err := db.Reindex(c); err != nil {
  110. log.Println("reindex:", err)
  111. }
  112. }
  113. func purgeIndex() {
  114. c := appengine.BackgroundContext()
  115. if err := database.PurgeIndex(c); err != nil {
  116. log.Println("purgeIndex:", err)
  117. }
  118. }