Skip to content

feat:fs s3 integration and tilesDeletionStartegy(MAPCO-9806)#24

Open
almog8k wants to merge 20 commits into
masterfrom
feat/fs-s3-integration
Open

feat:fs s3 integration and tilesDeletionStartegy(MAPCO-9806)#24
almog8k wants to merge 20 commits into
masterfrom
feat/fs-s3-integration

Conversation

@almog8k
Copy link
Copy Markdown
Collaborator

@almog8k almog8k commented May 6, 2026

Question Answer
New feature

This pull request introduces a complete implementation of a provider-agnostic tiles deletion strategy, supporting both S3 and filesystem backends. It adds new storage provider interfaces and implementations, integrates them into the DI container, and exposes configuration for provider-specific settings. The tiles deletion strategy now efficiently deletes tiles in batches, handles partial failures, and reports progress.

Tiles Deletion Strategy Implementation:

  • Implemented the TilesDeletionStrategy to support deleting tiles from both S3 and filesystem backends, including batching, concurrency, error handling, and progress reporting. The strategy uses provider abstraction and is fully configurable.

Storage Provider Abstraction:

  • Added the IStorageProvider interface and concrete implementations: S3StorageProvider (using @aws-sdk/client-s3) and FsStorageProvider (using Node.js file system APIs). These providers handle batch deletions and error handling specific to their storage type. [1] [2] [3] [4]
  • Registered the storage providers in the DI container and exposed them via the STORAGE_PROVIDERS symbol. [1] [2] [3] [4]

Configuration and Environment:

  • Added configuration and environment variable support for S3 and tiles deletion strategy parameters (such as bucket, base path, batch size, and concurrency) in config/default.json, config/custom-environment-variables.json, and Helm charts. [1] [2] [3] [4]

Dependency and Schema Updates:

  • Added dependencies on @aws-sdk/client-s3 and updated to use the tiles deletion schema and types from @map-colonies/raster-shared. [1] [2]

almog8k and others added 8 commits April 29, 2026 17:49
- Added "@aws-sdk/client-s3" dependency to package.json for S3 interactions.
- Introduced STORAGE_PROVIDERS constant in constants.ts for future storage provider implementations.
…pe imports

Co-authored-by: Copilot <copilot@github.com>
… strategy

Co-authored-by: Copilot <copilot@github.com>
@almog8k almog8k changed the title feat:fs s3 integration and tilesDeletionStartegy feat:fs s3 integration and tilesDeletionStartegy(MAPCO-9806) May 6, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

🎫 Related Jira Issue: MAPCO-9806

Comment thread config/default.json
"delay": "exponential",
"shouldResetTimeout": true
},
"s3": {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check if Storage Class is needed

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to specify the Storage Class when deleting an object because S3 only needs the object's exact "address" to find and destroy it.

private async cleanupEmptyDirs(relativePaths: string[], storageTarget: string): Promise<void> {
const dirsByLevel = new Map<number, Set<string>>();

for (const relativePath of relativePaths) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try to add more comment to explain what going on here

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments.

public constructor(
@inject(SERVICES.LOGGER) private readonly logger: Logger,
@inject(SERVICES.CONFIG) config: ConfigType,
@inject(SERVICES.STORAGE_PROVIDERS) private readonly storageProviders: Map<string, IStorageProvider>,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check if changed string to SourceType

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used(SourceType)

if (provider === undefined) {
throw new UnrecoverableError(`Unknown storage provider: ${params.sourceProvider}`);
}
const storageTarget = params.sourceProvider === 'S3' ? this.s3Bucket : this.fsBasePath;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use SourceType

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used(SourceType)

}

private countTiles(params: TilesDeletionParams): number {
return params.ranges.reduce((sum, r) => sum + (r.maxX - r.minX + 1) * (r.maxY - r.minY + 1), 0);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment to explain this code line

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment explaining the countTiles func

}

private async flushBatches(provider: IStorageProvider, storageTarget: string, pendingBatches: string[][], failedPaths: string[]): Promise<number> {
const flushedCount = pendingBatches.reduce((sum, b) => sum + b.length, 0);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add comment to explain

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added


if (failedPaths.length > 0) {
const sample = failedPaths.slice(0, this.failureSampleSize);
this.logger.warn({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to error log

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

pendingBatches.push(batch);
batch = [];
if (pendingBatches.length === this.concurrency) {
processedTiles += await this.flushBatches(provider, storageTarget, pendingBatches, failedPaths);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add info log indicate for x/total deleted

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log Added

Comment thread src/containerConfig.ts
useFactory: instancePerContainerCachingFactory((container) => {
const config = container.resolve<ConfigType>(SERVICES.CONFIG);
const logger = container.resolve<Logger>(SERVICES.LOGGER);
return new Map<string, IStorageProvider>([
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread package.json Outdated
"@godaddy/terminus": "^4.12.1",
"@map-colonies/config": "^4.0.1",
"@map-colonies/jobnik-sdk": "^0.1.0",
"@map-colonies/js-logger": "^3.0.2",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upgrade to 5.0.0

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgraded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants