runner.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package s3presign
  2. import (
  3. "context"
  4. "log/slog"
  5. "time"
  6. "google.golang.org/protobuf/types/known/timestamppb"
  7. "github.com/usememos/memos/plugin/storage/s3"
  8. storepb "github.com/usememos/memos/proto/gen/store"
  9. "github.com/usememos/memos/store"
  10. )
  11. type Runner struct {
  12. Store *store.Store
  13. }
  14. func NewRunner(store *store.Store) *Runner {
  15. return &Runner{
  16. Store: store,
  17. }
  18. }
  19. // Schedule runner every 12 hours.
  20. const runnerInterval = time.Hour * 12
  21. func (r *Runner) Run(ctx context.Context) {
  22. ticker := time.NewTicker(runnerInterval)
  23. defer ticker.Stop()
  24. for {
  25. select {
  26. case <-ticker.C:
  27. r.RunOnce(ctx)
  28. case <-ctx.Done():
  29. return
  30. }
  31. }
  32. }
  33. func (r *Runner) RunOnce(ctx context.Context) {
  34. r.CheckAndPresign(ctx)
  35. }
  36. func (r *Runner) CheckAndPresign(ctx context.Context) {
  37. workspaceStorageSetting, err := r.Store.GetWorkspaceStorageSetting(ctx)
  38. if err != nil {
  39. return
  40. }
  41. s3StorageType := storepb.ResourceStorageType_S3
  42. resources, err := r.Store.ListResources(ctx, &store.FindResource{
  43. GetBlob: false,
  44. StorageType: &s3StorageType,
  45. })
  46. if err != nil {
  47. return
  48. }
  49. for _, resource := range resources {
  50. s3ObjectPayload := resource.Payload.GetS3Object()
  51. if s3ObjectPayload == nil {
  52. continue
  53. }
  54. if s3ObjectPayload.LastPresignedTime != nil {
  55. // Skip if the presigned URL is still valid for the next 4 days.
  56. // The expiration time is set to 5 days.
  57. if time.Now().Before(s3ObjectPayload.LastPresignedTime.AsTime().Add(4 * 24 * time.Hour)) {
  58. continue
  59. }
  60. }
  61. s3Config := workspaceStorageSetting.GetS3Config()
  62. if s3ObjectPayload.S3Config != nil {
  63. s3Config = s3ObjectPayload.S3Config
  64. }
  65. if s3Config == nil {
  66. slog.Error("S3 config is not found")
  67. continue
  68. }
  69. s3Client, err := s3.NewClient(ctx, s3Config)
  70. if err != nil {
  71. slog.Error("Failed to create S3 client", "error", err)
  72. continue
  73. }
  74. presignURL, err := s3Client.PresignGetObject(ctx, s3ObjectPayload.Key)
  75. if err != nil {
  76. return
  77. }
  78. s3ObjectPayload.S3Config = s3Config
  79. s3ObjectPayload.LastPresignedTime = timestamppb.New(time.Now())
  80. if err := r.Store.UpdateResource(ctx, &store.UpdateResource{
  81. ID: resource.ID,
  82. Reference: &presignURL,
  83. Payload: &storepb.ResourcePayload{
  84. Payload: &storepb.ResourcePayload_S3Object_{
  85. S3Object: s3ObjectPayload,
  86. },
  87. },
  88. }); err != nil {
  89. return
  90. }
  91. }
  92. }