sourcefuse / sourcefuse/loopback4-microservice-catalog
POST /audit-logs/archive fails with socket hang up / ECONNREFUSED during archive cron run for large number of rows
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 297
- Forks
- 78
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 4
Description
The archive-audit-data cron job (cron-service) calls the audit-service archive API POST /audit-service/audit-logs/archive once per tenant. This API is owned and hosted by another team — we only invoke it and cannot scale or modify that service's infrastructure. On QA, the first tenant's archive request causes the audit-service to fail mid-request, and it stays unreachable for the rest of the run, so the remaining tenants also fail. As a result no audit data is archived and the cron records a failure entry per tenant.
it should be scale or consider batching/streaming the archive instead of loading the full result set into memory
Two distinct failures observed in a single run:
- First tenant → socket hang up (connection opened, but the server closed it before responding → service crashed/restarted mid-request).
- Subsequent tenants → connect ECONNREFUSED / connect EPERM 10.43.48.20:3000 (service no longer accepting connections → down/restarting after the first request).
Expected behavior
The archive API should handle each tenant's archival request without crashing or becoming unreachable, regardless of how many audit-log rows fall in the requested date window. A single tenant's request should not take the audit-service down for the remaining tenants. Each archive call should complete successfully (or return a clean, handled error) so audit data is archived as intended. it should be scale or consider batching/streaming the archive instead of loading the full result set into memory
Screenshots
N/A — backend cron job. Relevant log output and cron_runs.meta.error payloads are included above.
Additional context
- The archive API (POST /audit-service/audit-logs/archive) is owned and hosted by another team; cron-service only calls it. We are not able to scale or change that service's infrastructure, so the fix must come from the sourceloop team.
- API behavior (sourceloop @sourceloop/audit-service audit.controller.js): it runs auditLogRepository.find({where}) to load the entire matching result set into memory (no pagination/limit), CSV-exports it, then deleteAll. For a busy tenant over the requested window this is a large, unbounded in-memory operation — a likely cause of the crash (suspected OOM/restart).
- Failure cascade: socket hang up on the first tenant (server died mid-request) → ECONNREFUSED/EPERM for subsequent tenants (server down/unreachable). The EPERM may additionally point to a NetworkPolicy/egress or conntrack/socket exhaustion issue on the audit-service side.
- Suggested investigation for the sourceloop team: consider batching/streaming the archive instead of loading the full result set into memory; verify NetworkPolicy/egress between cron-service and audit-service.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in the sourceloop audit-service archive handler described as audit.controller.js, focusing on the auditLogRepository.find({where}) call and the subsequent CSV export and deleteAll steps. Reproduce with a large tenant/date range, then investigate bounded batching or streaming and verify that one tenant no longer takes the service down and remaining archive calls receive a handled result.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs, typescript
- Domain
- api, backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100