Skip to content

Commit 692444e

Browse files
authored
fix: prevent garbage collection from removing default profiles (#1843)
1 parent 6461a0a commit 692444e

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

content/src/service/garbage-collection/GarbageCollectionManager.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,17 @@ export class GarbageCollectionManager {
6767
// it will remove a max of ${PROFILE_CLEANUP_LIMIT}
6868
async gcStaleProfiles(oldProfileSince: Date): Promise<GCStaleProfilesResult> {
6969
const result = await this.components.database.queryWithValues<{ id: string; content_hash: string }>(
70-
SQL`SELECT d.id, cf.content_hash FROM deployments d left join content_files cf on cf.deployment = d.id WHERE d.entity_type = 'profile' AND entity_timestamp < ${oldProfileSince} LIMIT ${PROFILE_CLEANUP_LIMIT}`,
70+
SQL`SELECT d.id, cf.content_hash
71+
FROM deployments d
72+
LEFT JOIN content_files cf on cf.deployment = d.id
73+
WHERE d.entity_type = 'profile'
74+
AND entity_timestamp < ${oldProfileSince}
75+
AND NOT EXISTS (
76+
SELECT 1 FROM active_pointers ap
77+
WHERE ap.entity_id = d.entity_id
78+
AND ap.pointer ~ '^default[0-9]+$'
79+
)
80+
LIMIT ${PROFILE_CLEANUP_LIMIT}`,
7181
'gc_old_profiles_query_old_deployments'
7282
)
7383

@@ -134,7 +144,13 @@ export class GarbageCollectionManager {
134144
this.LOGGER.info('Running clear old profiles process')
135145

136146
const result = await this.components.database.queryWithValues<{ pointer: string }>(
137-
SQL`DELETE FROM active_pointers ap USING deployments d WHERE d.entity_id = ap.entity_id AND entity_type = 'profile' AND entity_timestamp < ${oldProfileSince} RETURNING ap.pointer`,
147+
SQL`DELETE FROM active_pointers ap
148+
USING deployments d
149+
WHERE d.entity_id = ap.entity_id
150+
AND entity_type = 'profile'
151+
AND entity_timestamp < ${oldProfileSince}
152+
AND ap.pointer !~ '^default[0-9]+$'
153+
RETURNING ap.pointer`,
138154
'gc_old_profiles_delete_active_pointers'
139155
)
140156

content/test/integration/service/garbage-collection/garbage-collection.spec.ts

+37
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,43 @@ describe('Integration - Garbage Collection', () => {
243243
expect(results?.gcStaleProfilesResult?.deletedHashes.size).toEqual(0)
244244
expect(results?.gcStaleProfilesResult?.deletedDeployments).toContain(p1DeploymentId)
245245
})
246+
247+
it('should not garbage collect default profiles even when they are old', async () => {
248+
const timestamp = Date.now() - PROFILE_DURATION * 2
249+
const defaultProfile = await buildDeployData(['default123'], {
250+
type: EntityType.PROFILE,
251+
contentPaths: [
252+
'test/integration/resources/some-binary-file.png',
253+
'test/integration/resources/some-text-file.txt'
254+
],
255+
timestamp,
256+
metadata: {}
257+
})
258+
259+
const regularProfile = await buildDeployData(['0x000000000'], {
260+
type: EntityType.PROFILE,
261+
contentPaths: [
262+
'test/integration/resources/some-binary-file.png',
263+
'test/integration/resources/some-text-file.txt'
264+
],
265+
timestamp,
266+
metadata: {}
267+
})
268+
269+
await deployEntitiesCombo(components.deployer, defaultProfile, regularProfile)
270+
const regularProfileDeploymentId = await findDeploymentId(regularProfile.entity.id)
271+
272+
await components.garbageCollectionManager.start()
273+
274+
const results = components.garbageCollectionManager.getLastSweepResults()
275+
276+
expect(results?.gcProfileActiveEntitiesResult).toContain(regularProfile.entity.pointers[0])
277+
expect(results?.gcStaleProfilesResult?.deletedDeployments).toContain(regularProfileDeploymentId)
278+
279+
expect(results?.gcProfileActiveEntitiesResult).not.toContain(defaultProfile.entity.pointers[0])
280+
const defaultProfileDeploymentId = await findDeploymentId(defaultProfile.entity.id)
281+
expect(results?.gcStaleProfilesResult?.deletedDeployments).not.toContain(defaultProfileDeploymentId)
282+
})
246283
})
247284

248285
async function assertContentIsAvailable(components: AppComponents, ...hashes: string[]) {

0 commit comments

Comments
 (0)