redis-cache-registry.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import { LatestVideosCacheBuilder } from '@box/core/cache/video/latest/latest-videos-cache.builder';
  2. import { RecommendedVideosCacheBuilder } from '@box/core/cache/video/recommended/recommended-videos-cache.builder';
  3. import { TagCacheBuilder } from '@box/core/cache/tag/tag-cache.builder';
  4. import { CategoryCacheBuilder } from '@box/core/cache/category/category-cache.builder';
  5. import { ChannelCacheBuilder } from '@box/core/cache/channel/channel-cache.builder';
  6. import { AdPoolBuilder } from '@box/core/ad/ad-pool.builder';
  7. export type RedisCacheCode =
  8. | 'VIDEO_LATEST'
  9. | 'VIDEO_RECOMMENDED'
  10. | 'TAG_ALL'
  11. | 'CATEGORY_ALL'
  12. | 'CATEGORY_BY_ID'
  13. | 'CHANNEL_ALL'
  14. | 'CHANNEL_BY_ID'
  15. | 'ADPOOL';
  16. export interface RedisCacheRebuildHandler {
  17. cacheCode: RedisCacheCode;
  18. label: string;
  19. description?: string;
  20. rebuild: () => Promise<{ ok: boolean; message?: string; affected?: number }>;
  21. }
  22. interface RedisCacheRegistryDeps {
  23. latestVideosCacheBuilder: LatestVideosCacheBuilder;
  24. recommendedVideosCacheBuilder: RecommendedVideosCacheBuilder;
  25. tagCacheBuilder: TagCacheBuilder;
  26. categoryCacheBuilder: CategoryCacheBuilder;
  27. channelCacheBuilder: ChannelCacheBuilder;
  28. adPoolBuilder: AdPoolBuilder;
  29. }
  30. export function getRedisCacheRegistry(
  31. deps: RedisCacheRegistryDeps,
  32. ): RedisCacheRebuildHandler[] {
  33. return [
  34. {
  35. cacheCode: 'VIDEO_LATEST',
  36. label: 'Latest Videos Cache',
  37. description: 'Rebuilds the latest video feed cache.',
  38. rebuild: async () => {
  39. await deps.latestVideosCacheBuilder.buildAll();
  40. return {
  41. ok: true,
  42. message: 'Latest videos cache rebuilt',
  43. };
  44. },
  45. },
  46. {
  47. cacheCode: 'VIDEO_RECOMMENDED',
  48. label: 'Recommended Videos Cache',
  49. description: 'Rebuilds the homepage recommended video cache.',
  50. rebuild: async () => {
  51. await deps.recommendedVideosCacheBuilder.buildAll();
  52. return {
  53. ok: true,
  54. message: 'Recommended videos cache rebuilt',
  55. };
  56. },
  57. },
  58. {
  59. cacheCode: 'TAG_ALL',
  60. label: 'Tag Cache',
  61. description: 'Rebuilds the global tag metadata cache.',
  62. rebuild: async () => {
  63. await deps.tagCacheBuilder.buildAll();
  64. return { ok: true, message: 'Tag cache rebuilt' };
  65. },
  66. },
  67. {
  68. cacheCode: 'CATEGORY_ALL',
  69. label: 'Category Cache (all)',
  70. description: 'Rebuilds the full category listing cache.',
  71. rebuild: async () => {
  72. await deps.categoryCacheBuilder.buildAll();
  73. return { ok: true, message: 'Category cache rebuilt' };
  74. },
  75. },
  76. {
  77. cacheCode: 'CHANNEL_ALL',
  78. label: 'Channel Cache (all)',
  79. description: 'Rebuilds the complete channel cache.',
  80. rebuild: async () => {
  81. await deps.channelCacheBuilder.buildAll();
  82. return { ok: true, message: 'Channel cache rebuilt' };
  83. },
  84. },
  85. {
  86. cacheCode: 'ADPOOL',
  87. label: 'Ad Pools',
  88. description: 'Rebuilds all ad pools.',
  89. rebuild: async () => {
  90. await deps.adPoolBuilder.buildAll();
  91. return { ok: true, message: 'Ad pools rebuilt' };
  92. },
  93. },
  94. ];
  95. }
  96. export interface RedisCacheKeyAllowListEntry {
  97. cacheCode: RedisCacheCode;
  98. matcher: (key: string) => boolean;
  99. description: string;
  100. }
  101. export const RedisCacheKeyAllowList: RedisCacheKeyAllowListEntry[] = [
  102. {
  103. cacheCode: 'VIDEO_LATEST',
  104. matcher: (key) => key === 'box:app:video:latest',
  105. description: 'Latest videos key',
  106. },
  107. {
  108. cacheCode: 'VIDEO_RECOMMENDED',
  109. matcher: (key) => key === 'box:app:video:recommended',
  110. description: 'Recommended videos key',
  111. },
  112. {
  113. cacheCode: 'TAG_ALL',
  114. matcher: (key) => key === 'box:app:tag:all',
  115. description: 'Global tag metadata key',
  116. },
  117. {
  118. cacheCode: 'CATEGORY_ALL',
  119. matcher: (key) => key === 'box:app:category:all',
  120. description: 'Category all key',
  121. },
  122. {
  123. cacheCode: 'CATEGORY_BY_ID',
  124. matcher: (key) => key.startsWith('box:app:category:by-id:'),
  125. description: 'Category detail key',
  126. },
  127. {
  128. cacheCode: 'CHANNEL_ALL',
  129. matcher: (key) => key === 'box:app:channel:all',
  130. description: 'Channel all key',
  131. },
  132. {
  133. cacheCode: 'CHANNEL_BY_ID',
  134. matcher: (key) => key.startsWith('box:app:channel:by-id:'),
  135. description: 'Channel detail key',
  136. },
  137. {
  138. cacheCode: 'ADPOOL',
  139. matcher: (key) => key.startsWith('box:app:adpool:'),
  140. description: 'Ad pool key',
  141. },
  142. ];