forked from istSOS/istSOS4
-
Notifications
You must be signed in to change notification settings - Fork 0
Week 04 Report
Vishmayraj Zala edited this page Aug 19, 2026
·
1 revision
I performed the following tasks during week 4:
Architecture migration: standalone to integrated
- Migrated the connector from the standalone microservice shape prototyped during bonding into the confirmed integrated architecture inside
api/app/v1/connector/within the main istSOS4 repo. Scaffolded all connector package files as per the structure agreed with mentors. - Added a temporary FROST migration utility to seed the local development environment with Fraunhofer's air quality dataset, allowing STAC development to proceed immediately without waiting for a populated local dataset. This commit will be reverted before the branch is merged.
Harvesting layer implementation (harvester.py)
- Implemented the harvesting layer using a direct asyncpg JOIN query across
Thing,Location,Datastream,ObservedProperty, andSensortables. The query runs in a single database round trip -- no application-level pagination or sequential HTTP fetches. On the Fraunhofer dataset (5,610 Things, 22,941 Datastreams), the query executes in 383.297 ms, confirming the architectural trade-off from the weeks 1-2 benchmarks was correct. - The LISTEN/NOTIFY cache invalidation approach, proposed in week 3, was reviewed with mentors and rejected. Triggers on the Postgres side introduce coupling between the SensorThings schema and the connector lifecycle; the connector is a pure reader and interval-based refresh is simpler, auditable, and sufficient.
HARVEST_INTERVAL_MINUTESin.envis the single control point. - asyncpg does not register a JSON/JSONB codec on the shared istSOS4 pool, and the existing STA read paths rely on that behaviour -- they stream pre-serialised JSON straight through without an intermediate
json.loads()/json.dumps()round trip. Registering a global codec would silently change behaviour for unrelated code. Instead,_coerce_json()decodes JSON columns locally, only for rows the harvester consumes, handling three cases:None, an already-decodeddict/list, and a raw JSON string. Malformed blobs log a warning and returnNonerather than failing the whole cycle.
Scheduling layer implementation (scheduler.py)
- Implemented APScheduler integration -- as advised by Maxi in our last meeting -- wired into the istSOS4 application lifespan in
main.py. The scheduler starts on application startup and fires_run_cycleat the interval configured in.env. - Implemented a Postgres advisory lock -- as advised by Maxi in our last meeting -- acquired before harvest begins and held for the entire cycle duration: harvest, both transforms, and both cache writes. This prevents duplicate execution across multiple Uvicorn workers without a distributed lock service. The advisory lock connection is kept separate from the harvest connection so the harvest query does not block on lock management.
- STAC and DCAT writes inside
_run_cycleare independent. A DCAT failure does not roll back the STAC write. The DCAT path is guarded behind aNonecheck onbuild_dcat_catalogand logs a warning each cycle untildcat_transformer.pyis implemented, leaving STAC serving unaffected in the interim.
Details can be found in:
- Harvesting layer:
api/app/v1/connector/harvester.py - Scheduling layer:
api/app/v1/connector/scheduler.py
What do I plan to do next week?
- Implement
stac_transformer.pyandcache.py. - Implement the connector API router and wire it into the main FastAPI application.
- Have a running end-to-end STAC pipeline serving responses by end of week.
Am I blocked on anything?
No blockages.