Conversation
packages/twenty-server/src/engine/workspace-cache/services/workspace-cache.service.ts
Outdated
Show resolved
Hide resolved
...ne/metadata-modules/workspace-permissions-cache/workspace-roles-permissions-cache.service.ts
Outdated
Show resolved
Hide resolved
|
🚀 Preview Environment Ready! Your preview environment is available at: http://bore.pub:53705 This environment will automatically shut down when the PR is closed or after 5 hours. |
|
@greptileai trigger |
Greptile OverviewGreptile SummaryThis PR successfully consolidates workspace-level caching into a unified Key Improvements:
Migration Impact:
Confidence Score: 5/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Client as Service/Controller
participant WCS as WorkspaceCacheService
participant Local as Local Cache (Map)
participant Memoizer as Promise Memoizer
participant Redis as Redis (CacheStorageService)
participant Provider as Cache Provider
Client->>WCS: getOrRecompute(workspaceId, keys)
WCS->>Memoizer: Check memoized result
alt Result in Memoizer (< 10s)
Memoizer-->>WCS: Return cached result
WCS-->>Client: Return data
else Not in Memoizer
WCS->>Local: Check local cache (TTL 100ms)
alt Fresh in Local Cache
Local-->>WCS: Return fresh data
WCS-->>Client: Return data
else Stale in Local Cache
WCS->>Redis: MGET hash keys
Redis-->>WCS: Return hashes
alt Hash matches local
WCS->>Local: Update timestamp
WCS-->>Client: Return local data
else Hash mismatch or missing
WCS->>Redis: MGET data keys
Redis-->>WCS: Return data
alt Data exists in Redis
WCS->>Local: Store with new hash
WCS-->>Client: Return Redis data
else Data missing
WCS->>Provider: computeForCache(workspaceId)
Provider->>Provider: Query database
Provider-->>WCS: Return computed data
WCS->>Redis: MSET data + hash via pipeline
WCS->>Local: Store with hash
WCS->>Memoizer: Cache result
WCS-->>Client: Return computed data
end
end
end
end
Note over Client,Provider: Invalidation Flow
Client->>WCS: invalidateAndRecompute(workspaceId, keys)
WCS->>Memoizer: clearKeys(prefix)
WCS->>Redis: MDEL data + hash keys
WCS->>Local: Delete entries
WCS->>Provider: computeForCache(workspaceId)
Provider-->>WCS: Fresh data
WCS->>Redis: MSET data + hash
WCS->>Local: Store with hash
WCS-->>Client: Done
|
| return; | ||
| } | ||
|
|
||
| if (this.isRedisCache()) { |
There was a problem hiding this comment.
this should move to the driver but OK given the current state of other method of cache-storage service
|
|
||
| import { ALL_FLAT_ENTITY_MAPS_PROPERTIES } from 'src/engine/metadata-modules/flat-entity/constant/all-flat-entity-maps-properties.constant'; | ||
| import { AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; | ||
| import { WorkspaceFlatMapCacheRegistryService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache-registry.service'; | ||
| import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service'; | ||
| import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; | ||
|
|
||
| @Injectable() | ||
| export class WorkspaceManyOrAllFlatEntityMapsCacheService { |
There was a problem hiding this comment.
I guess we can get rid of this service?
There was a problem hiding this comment.
Yes, I'm in favor of this as well but I'm leaving as it is for now to avoid conflict with prastoin work. @charlesBochet
...ne/metadata-modules/workspace-permissions-cache/workspace-roles-permissions-cache.service.ts
Show resolved
Hide resolved
| 'rolesPermissions', | ||
| ]); | ||
|
|
||
| const cachedFeatureFlagMapVersion = crypto |
There was a problem hiding this comment.
I'm a bit of surprise we have to compute this here, shouldn't it be the hashVersion directly?
There was a problem hiding this comment.
it's for legacy only, the cache service does not expose those keys and they are needed for the legacy datasource so I'm recomputing them again here. (this won't be needed later though) @charlesBochet
| @@ -96,6 +96,12 @@ export class PromiseMemoizer<T> { | |||
| await this.clearKey(cacheKey, onDelete); | |||
| } | |||
| } | |||
|
|
|||
| for (const cacheKey of [...this.pending.keys()]) { | |||
| import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; | ||
| import { type UserWorkspaceRoleMap } from 'src/engine/metadata-modules/workspace-permissions-cache/types/user-workspace-role-map.type'; | ||
|
|
||
| export const WORKSPACE_CACHE_KEYS_V2 = { |
| }, | ||
| ), | ||
| ], | ||
| this.workspaceCacheService.invalidateAndRecompute(workspaceId, [ |
Context
We've recently introduced a new workspace cache service which now acts as a cache access and local storage for all workspace related data, deprecating the individual specific services.