Skip to content

Commit d907907

Browse files
committed
refactor: more solid and simple structure
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
1 parent 618cae4 commit d907907

21 files changed

Lines changed: 710 additions & 542 deletions

File tree

backend/.env.dist.local

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -199,34 +199,14 @@ OSV_ECOSYSTEMS=npm,Maven
199199
OSV_TMP_DIR=/tmp/osv
200200
OSV_BATCH_SIZE=500
201201
OSV_DERIVE_BATCH_SIZE=1000
202-
# pom-fetcher non-critical (DB-only)
203-
POM_FETCHER_NON_CRITICAL_BATCH_SIZE=500
204-
POM_FETCHER_NON_CRITICAL_CONCURRENCY=20
205-
206-
# pom-fetcher critical (HTTP)
207-
POM_FETCHER_BATCH_SIZE=100
208-
POM_FETCHER_CONCURRENCY=5
209-
# ── non-critical DB-only (usato quando DIRECT_POM_FOR_ALL=false) ──────────────
210-
# POM_FETCHER_NON_CRITICAL_BATCH_SIZE=500
211-
POM_FETCHER_NON_CRITICAL_CONCURRENCY=20 # solo DB writes, nessun HTTP
212-
POM_FETCHER_NON_CRITICAL_REFRESH_DAYS=1
213-
214-
# ── non-critical HTTP / direct-pom (usato quando DIRECT_POM_FOR_ALL=true) ─────
215-
# POM_FETCHER_NON_CRITICAL_POM_CONCURRENCY=5
216-
# POM_FETCHER_NON_CRITICAL_POM_REFRESH_DAYS=1
217-
218-
# ── critical HTTP / full-pom (sempre attivo) ──────────────────────────────────
219-
# POM_FETCHER_BATCH_SIZE=100
220-
# POM_FETCHER_CONCURRENCY=5
221-
# POM_FETCHER_FULL_REFRESH_DAYS=1
222-
223-
# ── modalità e rate limiting ──────────────────────────────────────────────────
224-
# POM_FETCHER_DIRECT_POM_FOR_ALL=true
225-
# POM_FETCHER_GROUP_DELAY_MS=200
226-
227-
202+
# maven enricher
228203
POM_FETCHER_BATCH_SIZE=50
229204
POM_FETCHER_CONCURRENCY=3
205+
POM_FETCHER_NON_CRITICAL_BATCH_SIZE=500
206+
POM_FETCHER_NON_CRITICAL_CONCURRENCY=20
230207
POM_FETCHER_REFRESH_DAYS=1
231208
POM_FETCHER_GROUP_DELAY_MS=500
232209
POM_FETCHER_IDLE_SLEEP_SEC=3600
210+
# Set to 'true' on first run against a fresh/restored DB to skip the version-unchanged
211+
# optimisation and force full POM extraction. Set to 'false' after the first pass.
212+
POM_FETCHER_FORCE_FULL_EXTRACTION=false
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version: '3.1'
33
x-env-args: &env-args
44
DOCKER_BUILDKIT: 1
55
NODE_ENV: docker
6-
SERVICE: pom-fetcher
6+
SERVICE: maven
77
SHELL: /bin/sh
88
SUPPRESS_NO_CONFIG_WARNING: 'true'
99
LOG_LEVEL: 'info'
@@ -14,11 +14,11 @@ x-env-args: &env-args
1414
POM_FETCHER_IDLE_SLEEP_SEC: '3600'
1515

1616
services:
17-
pom-fetcher:
17+
maven:
1818
build:
1919
context: ../../
2020
dockerfile: ./scripts/services/docker/Dockerfile.packages-worker
21-
command: 'pnpm run start:pom-fetcher'
21+
command: 'pnpm run start:maven'
2222
working_dir: /usr/crowd/app/services/apps/packages_worker
2323
env_file:
2424
- ../../backend/.env.dist.local
@@ -31,11 +31,11 @@ services:
3131
networks:
3232
- crowd-bridge
3333

34-
pom-fetcher-dev:
34+
maven-dev:
3535
build:
3636
context: ../../
3737
dockerfile: ./scripts/services/docker/Dockerfile.packages-worker
38-
command: 'pnpm run dev:pom-fetcher'
38+
command: 'pnpm run dev:maven'
3939
working_dir: /usr/crowd/app/services/apps/packages_worker
4040
# user: '${USER_ID}:${GROUP_ID}'
4141
env_file:
@@ -45,7 +45,7 @@ services:
4545
- ../../backend/.env.override.composed
4646
environment:
4747
<<: *env-args
48-
hostname: pom-fetcher
48+
hostname: maven
4949
networks:
5050
- crowd-bridge
5151
volumes:

services/apps/packages_worker/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
"start:packages-worker": "CROWD_TEMPORAL_TASKQUEUE=packages-worker CROWD_TEMPORAL_NAMESPACE=$CROWD_PACKAGES_TEMPORAL_NAMESPACE SERVICE=packages-worker tsx src/bin/packages-worker.ts",
66
"start:deps-dev-ingest": "CROWD_TEMPORAL_TASKQUEUE=deps-dev-ingest CROWD_TEMPORAL_NAMESPACE=$CROWD_PACKAGES_TEMPORAL_NAMESPACE SERVICE=deps-dev-ingest tsx src/bin/deps-dev-ingest.ts",
77
"start:github-repos-enricher": "SERVICE=github-repos-enricher tsx src/bin/github-repos-enricher.ts",
8-
"start:pom-fetcher": "SERVICE=pom-fetcher tsx src/bin/pom-fetcher.ts",
8+
"start:maven": "SERVICE=maven tsx src/bin/maven.ts",
99
"dev:packages-worker": "CROWD_TEMPORAL_TASKQUEUE=packages-worker CROWD_TEMPORAL_NAMESPACE=$CROWD_PACKAGES_TEMPORAL_NAMESPACE SERVICE=packages-worker LOG_LEVEL=trace nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9233 src/bin/packages-worker.ts",
1010
"dev:deps-dev-ingest": "CROWD_TEMPORAL_TASKQUEUE=deps-dev-ingest CROWD_TEMPORAL_NAMESPACE=$CROWD_PACKAGES_TEMPORAL_NAMESPACE SERVICE=deps-dev-ingest nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9235 src/bin/deps-dev-ingest.ts",
1111
"dev:github-repos-enricher": "SERVICE=github-repos-enricher LOG_LEVEL=trace nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9234 src/bin/github-repos-enricher.ts",
12+
"dev:maven": "SERVICE=maven LOG_LEVEL=info nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9235 src/bin/maven.ts",
1213
"dev:packages-worker:local": "set -a && . ../../../backend/.env.dist.local && . ../../../backend/.env.override.local && set +a && CROWD_TEMPORAL_TASKQUEUE=packages-worker CROWD_TEMPORAL_NAMESPACE=$CROWD_PACKAGES_TEMPORAL_NAMESPACE SERVICE=packages-worker LOG_LEVEL=trace nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9233 src/bin/packages-worker.ts",
1314
"dev:deps-dev-ingest:local": "set -a && . ../../../backend/.env.dist.local && . ../../../backend/.env.override.local && set +a && CROWD_TEMPORAL_TASKQUEUE=deps-dev-ingest CROWD_TEMPORAL_NAMESPACE=$CROWD_PACKAGES_TEMPORAL_NAMESPACE SERVICE=deps-dev-ingest nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9235 src/bin/deps-dev-ingest.ts",
1415
"dev:github-repos-enricher:local": "set -a && . ../../../backend/.env.dist.local && . ../../../backend/.env.override.local && set +a && SERVICE=github-repos-enricher LOG_LEVEL=trace nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9234 src/bin/github-repos-enricher.ts",
@@ -18,8 +19,7 @@
1819
"export-to-bucket": "SERVICE=deps-dev-ingest tsx src/scripts/exportToBucket.ts",
1920
"export-to-bucket:local": "set -a && . ../../../backend/.env.dist.local && . ../../../backend/.env.override.local && set +a && SERVICE=deps-dev-ingest tsx src/scripts/exportToBucket.ts",
2021
"monitor:osspckgs:local": "bash -c 'set -a && . ../../../backend/.env.dist.local && . ../../../backend/.env.override.local && set +a && node ../../../scripts/monitor-osspckgs.mjs'",
21-
"dev:pom-fetcher": "SERVICE=pom-fetcher LOG_LEVEL=info nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9235 src/bin/pom-fetcher.ts",
22-
"dev:pom-fetcher:local": "set -a && . ../../../backend/.env.dist.local && . ../../../backend/.env.override.local && set +a && SERVICE=pom-fetcher LOG_LEVEL=info nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9235 src/bin/pom-fetcher.ts",
22+
"dev:maven:local": "set -a && . ../../../backend/.env.dist.local && . ../../../backend/.env.override.local && set +a && SERVICE=maven LOG_LEVEL=info nodemon --watch src --watch ../../libs --ext ts --exec tsx --inspect=0.0.0.0:9235 src/bin/maven.ts",
2323
"lint": "npx eslint --ext .ts src --max-warnings=0",
2424
"format": "npx prettier --write \"src/**/*.ts\"",
2525
"format-check": "npx prettier --check .",
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export * from './deps-dev/activities'
22
export * from './npm/activities'
33
export { osvSyncEcosystem, osvDeriveCriticalFlag } from './osv/activities'
4-
export { processMavenCriticalBatch, processMavenNonCriticalBatch } from './pom-fetcher/activities'
4+
export { processMavenCriticalBatch, processMavenNonCriticalBatch } from './maven/activities'
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { getServiceLogger } from '@crowd/logging'
22

3-
import { getPomFetcherConfig } from '../config'
3+
import { getMavenConfig } from '../config'
44
import { getPackagesDb } from '../db'
5-
import { runPomEnrichmentLoop } from '../pom-fetcher/runPomEnrichmentLoop'
5+
import { runMavenEnrichmentLoop } from '../maven/runMavenEnrichmentLoop'
66

77
const log = getServiceLogger()
88

@@ -11,29 +11,29 @@ let shuttingDown = false
1111
const shutdown = async () => {
1212
if (shuttingDown) return
1313
shuttingDown = true
14-
log.info('Shutting down pom-fetcher...')
14+
log.info('Shutting down maven...')
1515
}
1616

1717
process.on('SIGINT', shutdown)
1818
process.on('SIGTERM', shutdown)
1919

2020
const main = async () => {
21-
log.info('pom-fetcher starting...')
21+
log.info('maven starting...')
2222

23-
const config = getPomFetcherConfig()
23+
const config = getMavenConfig()
2424
log.info(config, 'Config loaded')
2525

2626
const qx = await getPackagesDb()
2727
await qx.selectOne('SELECT 1')
2828
log.info('Connected to packages-db.')
2929

30-
await runPomEnrichmentLoop(qx, config, () => shuttingDown)
30+
await runMavenEnrichmentLoop(qx, config, () => shuttingDown)
3131

32-
log.info('pom-fetcher stopped.')
32+
log.info('maven stopped.')
3333
process.exit(0)
3434
}
3535

3636
main().catch((err) => {
37-
log.error({ err }, 'pom-fetcher fatal error')
37+
log.error({ err }, 'maven fatal error')
3838
process.exit(1)
3939
})
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { scheduleNpmIngest } from '../npm/schedule'
22
import { scheduleOsvSync } from '../osv/schedule'
3-
import { schedulePomFetcher } from '../pom-fetcher/schedule'
3+
import { scheduleMavenCritical, scheduleMavenNonCritical } from '../maven/schedule'
44
import { svc } from '../service'
55

66
setImmediate(async () => {
77
await svc.init()
88
await scheduleNpmIngest()
99
await scheduleOsvSync()
10-
await schedulePomFetcher()
10+
await scheduleMavenCritical()
11+
await scheduleMavenNonCritical()
1112
await svc.start()
1213
})

services/apps/packages_worker/src/config.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,15 @@ export function getEnricherConfig() {
3333
}
3434
}
3535

36-
export function getPomFetcherConfig() {
36+
export function getMavenConfig() {
3737
return {
38-
batchSize: parseInt(process.env.POM_FETCHER_BATCH_SIZE ?? '50', 10),
39-
concurrency: parseInt(process.env.POM_FETCHER_CONCURRENCY ?? '5', 10),
40-
refreshDays: parseInt(process.env.POM_FETCHER_REFRESH_DAYS ?? '1', 10),
41-
groupDelayMs: parseInt(process.env.POM_FETCHER_GROUP_DELAY_MS ?? '200', 10),
42-
idleSleepSec: parseInt(process.env.POM_FETCHER_IDLE_SLEEP_SEC ?? '3600', 10),
38+
batchSize: requireEnvInt('POM_FETCHER_BATCH_SIZE'),
39+
concurrency: requireEnvInt('POM_FETCHER_CONCURRENCY'),
40+
nonCriticalBatchSize: requireEnvInt('POM_FETCHER_NON_CRITICAL_BATCH_SIZE'),
41+
nonCriticalConcurrency: requireEnvInt('POM_FETCHER_NON_CRITICAL_CONCURRENCY'),
42+
refreshDays: requireEnvInt('POM_FETCHER_REFRESH_DAYS'),
43+
groupDelayMs: requireEnvInt('POM_FETCHER_GROUP_DELAY_MS'),
44+
idleSleepSec: requireEnvInt('POM_FETCHER_IDLE_SLEEP_SEC'),
45+
forceFullExtraction: requireEnv('POM_FETCHER_FORCE_FULL_EXTRACTION') === 'true',
4346
}
4447
}

services/apps/packages_worker/src/pom-fetcher/README.md renamed to services/apps/packages_worker/src/maven/README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,12 @@ The POM fetcher seeds `repos` with URL-derivable fields only. The GitHub enriche
127127

128128
| Value | Meaning |
129129
|-------|---------|
130-
| `pom_fetcher` | Critical — full POM + parent resolution succeeded |
131-
| `pom_fetcher_direct` | Non-critical — direct POM fetch succeeded (no parent resolution) |
132-
| `pom_fetcher_not_on_central` | `maven-metadata.xml` not found on `repo1.maven.org` — artifact is hosted on a third-party repository (e.g. WSO2 Nexus, JBoss, Atlassian). Universe data came from an aggregator (deps.dev, OSV). |
133-
| `pom_fetcher_no_version` | `maven-metadata.xml` found but `<release>` is empty — artifact has no stable release |
134-
| `pom_fetcher_error` | `maven-metadata.xml` has a release version but the `.pom` file for that version is a 404. Typical cause: partial deploy to Maven Central (metadata updated, artifact not uploaded) or Eclipse P2 feature artifacts that don't publish a standard POM. |
135-
| `pom_fetcher_rate_limited` | Maven Central returned 403/429 on all retry attempts. Package will be retried on the next pass. |
130+
| `maven` | Critical — full POM + parent resolution succeeded |
131+
| `maven_direct` | Non-critical — direct POM fetch succeeded (no parent resolution) |
132+
| `maven_not_on_central` | `maven-metadata.xml` not found on `repo1.maven.org` — artifact is hosted on a third-party repository (e.g. WSO2 Nexus, JBoss, Atlassian). Universe data came from an aggregator (deps.dev, OSV). |
133+
| `maven_no_version` | `maven-metadata.xml` found but `<release>` is empty — artifact has no stable release |
134+
| `maven_error` | `maven-metadata.xml` has a release version but the `.pom` file for that version is a 404. Typical cause: partial deploy to Maven Central (metadata updated, artifact not uploaded) or Eclipse P2 feature artifacts that don't publish a standard POM. |
135+
| `maven_rate_limited` | Maven Central returned 403/429 on all retry attempts. Package will be retried on the next pass. |
136136
| `packages_universe` | Non-critical, DB-only mode (`POM_FETCHER_DIRECT_POM_FOR_ALL=false`) — only universe stats copied |
137137

138138
---
@@ -143,19 +143,19 @@ The POM fetcher seeds `repos` with URL-derivable fields only. The GitHub enriche
143143

144144
WSO2 publishes some artifacts exclusively to their own Nexus at `maven.wso2.org`. A subset of their artifacts appear in `packages_universe` (sourced from deps.dev/OSV which aggregates all Maven repositories) but are **not** available on `repo1.maven.org/maven2`.
145145

146-
Affected pattern: `org.wso2.carbon.*` — specifically `.feature` Eclipse P2 artifacts and `.stub` artifacts. These are written with `ingestion_source = 'pom_fetcher_not_on_central'` and are not retried until the next `nonCriticalPomRefreshDays` window.
146+
Affected pattern: `org.wso2.carbon.*` — specifically `.feature` Eclipse P2 artifacts and `.stub` artifacts. These are written with `ingestion_source = 'maven_not_on_central'` and are not retried until the next `nonCriticalPomRefreshDays` window.
147147

148148
### Eclipse P2 Feature Artifacts (`*.feature`)
149149

150-
Eclipse/OSGi feature artifacts (e.g. `org.wso2.carbon.identity.xacml.server.feature`) are packaged as `.zip` files, not `.jar`. Some publishers update `maven-metadata.xml` on Central without uploading the corresponding `.pom`. These land in `pom_fetcher_error`. No fix is possible without the publisher correcting their CI/CD pipeline.
150+
Eclipse/OSGi feature artifacts (e.g. `org.wso2.carbon.identity.xacml.server.feature`) are packaged as `.zip` files, not `.jar`. Some publishers update `maven-metadata.xml` on Central without uploading the corresponding `.pom`. These land in `maven_error`. No fix is possible without the publisher correcting their CI/CD pipeline.
151151

152152
### Maven Central 403 rate limiting
153153

154154
Maven Central (`repo1.maven.org`) restituisce 403 come meccanismo di throttle oltre al canonico 429. Il comportamento è gestito a due livelli:
155155

156156
1. **Retry con backoff esponenziale** — 403 e 429 vengono ritentati fino a 3 volte (2s base, ×2 per tentativo). Gestito in `getWithRetry` (extract.ts) e `resolveVersionsList` (metadata.ts).
157157

158-
2. **Fallback su DB** — se tutti i retry esauriscono, il pacchetto viene scritto con `ingestion_source = 'pom_fetcher_rate_limited'` e `last_synced_at = NOW()`, evitando loop infiniti. Verrà ritentato al prossimo ciclo di refresh.
158+
2. **Fallback su DB** — se tutti i retry esauriscono, il pacchetto viene scritto con `ingestion_source = 'maven_rate_limited'` e `last_synced_at = NOW()`, evitando loop infiniti. Verrà ritentato al prossimo ciclo di refresh.
159159

160160
**Causa root dei 403 persistenti:** `packages_universe` è ordinato per `rank_in_ecosystem`, quindi pacchetti dello stesso namespace (es. `com.google.apis`, `org.wso2`, `software.amazon.awssdk`) si raggruppano nel batch e colpiscono lo stesso CDN node di Maven Central in rapida successione. Il rate limit scatta sistematicamente dopo ~150–200 pacchetti processati.
161161

@@ -167,7 +167,7 @@ Namespace noti per triggerare il rate limit a causa dell'alta densità di artefa
167167

168168
### Partial Maven Central Deploys
169169

170-
Occasionally a publisher's CI/CD updates `<release>` in `maven-metadata.xml` before the `.pom` is fully propagated to all Central mirrors. These appear as `pom_fetcher_error` on the first pass and usually resolve on the next periodic refresh.
170+
Occasionally a publisher's CI/CD updates `<release>` in `maven-metadata.xml` before the `.pom` is fully propagated to all Central mirrors. These appear as `maven_error` on the first pass and usually resolve on the next periodic refresh.
171171

172172
---
173173

@@ -221,7 +221,7 @@ The daily Temporal schedule has a **12-hour workflow timeout**. With `POM_FETCHE
221221

222222
## Scheduling
223223

224-
Runs daily at **4am UTC** via Temporal schedule `maven-pom-fetcher`.
224+
Runs daily at **4am UTC** via Temporal schedule `maven`.
225225
Overlap policy: `SKIP` — if a previous run is still active, the new trigger is dropped.
226226
Catchup window: 1 hour.
227227
Workflow timeout: 12 hours.
@@ -274,9 +274,9 @@ ORDER BY packages DESC;
274274
```
275275

276276
Expected behaviour:
277-
- `pom_fetcher` (critical, full resolution) → high repo coverage
278-
- `pom_fetcher_direct` (non-critical, no parent resolution) → low repo coverage
279-
- `pom_fetcher_not_on_central` / `pom_fetcher_error` → no repo (no POM data)
277+
- `maven` (critical, full resolution) → high repo coverage
278+
- `maven_direct` (non-critical, no parent resolution) → low repo coverage
279+
- `maven_not_on_central` / `maven_error` → no repo (no POM data)
280280

281281
Repo coverage will grow naturally as the critical package set expands and as non-critical packages hit their 30-day POM refresh window.
282282

services/apps/packages_worker/src/pom-fetcher/activities.ts renamed to services/apps/packages_worker/src/maven/activities.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import { getServiceChildLogger } from '@crowd/logging'
22

3-
import { getPomFetcherConfig } from '../config'
3+
import { getMavenConfig } from '../config'
44
import { getPackagesDb } from '../db'
5-
import { BatchResult, processBatch } from './runPomEnrichmentLoop'
5+
import { BatchResult, processBatch } from './runMavenEnrichmentLoop'
66

7-
const log = getServiceChildLogger('pom-fetcher-activity')
7+
const log = getServiceChildLogger('maven-activity')
88

99
export async function processMavenCriticalBatch(): Promise<BatchResult> {
10-
const config = getPomFetcherConfig()
10+
const config = getMavenConfig()
1111
const qx = await getPackagesDb()
1212
const result = await processBatch(qx, config, true)
13-
log.info({ processed: result.processed, skipped: result.skipped, errors: result.errors }, 'Maven critical batch complete')
13+
log.info({ processed: result.processed, skipped: result.skipped, unchanged: result.unchanged, error: result.error }, 'Maven critical batch complete')
1414
return result
1515
}
1616

1717
export async function processMavenNonCriticalBatch(): Promise<BatchResult> {
18-
const config = getPomFetcherConfig()
18+
const config = getMavenConfig()
1919
const qx = await getPackagesDb()
2020
const result = await processBatch(qx, config, false)
21-
log.info({ processed: result.processed, skipped: result.skipped, errors: result.errors }, 'Maven non-critical batch complete')
21+
log.info({ processed: result.processed, skipped: result.skipped, unchanged: result.unchanged, error: result.error }, 'Maven non-critical batch complete')
2222
return result
2323
}

0 commit comments

Comments
 (0)