Skip to content

feat: Entity Resolution Service v1.1.0#14

Merged
costezki merged 102 commits into
OP-TED:developfrom
meaningfy-ws:develop
May 15, 2026
Merged

feat: Entity Resolution Service v1.1.0#14
costezki merged 102 commits into
OP-TED:developfrom
meaningfy-ws:develop

Conversation

@gkostkowski

Copy link
Copy Markdown
Contributor

Summary

Sync meaningfy-ws/developOP-TED/develop for the v1.1.0 release of the Entity Resolution Service.

What's new in 1.1.0

Added

  • Immediate provisional mode (ERS_COORDINATOR_*_TIME_BUDGET=0) — returns a provisional identifier without waiting for ERE
  • Stateless multi-instance deployment via Redis Pub/Sub cross-instance notification
  • Optional TLS support for Redis connections (REDIS_TLS)
  • HTTP 503 / ServiceUnavailableError on MongoDB and Redis infrastructure outages across all endpoints
  • Configurable entity display name field per entity type (entity_label_field); returned by /entity-types
  • Exponential backoff with jitter for OutcomeIntegrationWorker reconnect on Redis failures
  • Socket connect timeout for the Redis subscriber worker
  • Black-box end-to-end ERSys test suite (migrated from er-ops)
  • ERS_SUBSCRIBER_READY_TIMEOUT startup readiness gate

Changed

  • ERE_REQUEST_CHANNEL / ERE_RESPONSE_CHANNEL renamed to ERSYS_REQUEST_CHANNEL / ERSYS_RESPONSE_CHANNEL — update .env files accordingly
  • display_name_field renamed to entity_label_field in entity-type configuration
  • REST API error field renamed from error to message; SERVICE_UNAVAILABLE added to all error enums
  • POST /refreshBulk returns only decisions whose cluster placement changed
  • Dependency versions pinned to exact values for reproducible builds

Fixed

  • Redis subscriber resilience: backoff reset on success, subscribed event cleared on stop(), aclose() guaranteed on cancel, malformed Pub/Sub payloads skipped
  • Redis client: TimeoutError wrapping in publish_notification
  • Configuration: identifier property path and full_address field for real TED data

gkostkowski and others added 30 commits April 28, 2026 16:43
…is 0

Both ERS_COORDINATOR_SINGLE_REQUEST_TIME_BUDGET and ERS_COORDINATOR_BULK_REQUEST_TIME_BUDGET
now accept 0 as a valid value. When single budget is 0, resolve_single skips ERE submission
entirely and issues a provisional identifier without any Redis interaction. When bulk budget
is 0, resolve_bulk removes the outer asyncio.wait_for timeout and lets the gather run untimed.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Python loggers are process-wide singletons; setting propagate=False in
create_app() permanently broke pytest caplog for all ers.* loggers across
the test session. Records still reach uvicorn handlers via the explicit
addHandler call, so Docker log visibility is unaffected.
feat: add immediate provisional mode (ERS_COORDINATOR_*_TIME_BUDGET=0), fix logging bug
Replace the in-process waiter.notify() callback with a Redis Pub/Sub broadcast
so all ERS instances receive ERE outcome notifications regardless of which instance
wins the BRPOP race. Enables correct horizontal scaling.

- Add ERS_NOTIFICATIONS_CHANNEL config property to RedisConfig
- Add publish_notification() to RedisEREClient (reuses existing connection pool)
- Add NotificationSubscriberWorker: asyncio background task, SUBSCRIBE loop,
  exponential backoff reconnect (1s-30s), subscribed asyncio.Event for readiness
- Wire subscriber worker and updated on_outcome_stored lambda in app.py lifespan
- Unit, integration, and BDD tests for all new behaviour
NotificationSubscriberWorker was creating its aioredis.Redis connection
without a socket connect timeout, leaving the subscribe call able to
block indefinitely if Redis was slow or hung.

- Add REDIS_SOCKET_CONNECT_TIMEOUT to RedisConfig (default 5.0 s)
- Add socket_connect_timeout field to RedisConnectionConfig, populated
  via from_settings()
- Forward it to aioredis.Redis() in NotificationSubscriberWorker.run()
- Add config and worker unit tests
- Update configuration.md (new entry + fix ERS_NOTIFICATIONS_CHANNEL
  description: Pub/Sub channel, not a list key)
…-instance notifications

Merge the two separate interaction diagrams (same-instance and cross-instance
BRPOP wins) into a single diagram with an alt/else block, add prose descriptions
of both cases above it, and add debug-level log statements in app.py and
notification_subscriber_worker.py to trace which path is taken at runtime.
Add ServiceUnavailableError subclassing ApplicationError for signalling
unreachable backend services (MongoDB, Redis). Also add pythonpath to
pytest.ini so the worktree src/ takes precedence over the shared
editable install when running tests.
…tcomeIntegrationWorker

Backoff starts at 1s, doubles on each consecutive ConnectionError, and is capped at 30s.
It resets to 1s after any successful message receive.
gkostkowski and others added 27 commits May 11, 2026 18:59
Propagate the two config changes from src/config/rdf_mention_config.yaml
into all test fixtures, factories and BDD step definitions:

- ORGANISATION: add full_address (cccev:registeredAddress/locn:fullAddress)
- PROCEDURE: update identifier path to adms:identifier/skos:notation
- Add skos namespace to sample fixture (now 7 namespaces)

Files updated: sample_rdf_mapping.yaml, factories.py,
test_rdf_mapping_config_reader.py, test_rdf_mapping_config.py,
test_mention_parser_service.py, parser_configuration.feature,
rdf_parsing.feature and their step definitions,
ers_rest_api conftest stub.
feat: add black-box ERSys test suite migrated from er-ops
…s-config

fix(config): rename ERE_REQUEST/RESPONSE_CHANNEL env vars to ERSYS_ prefix
fix(config): update rdf_mention_config and align test fixtures with real TED data
Pin coordinator config to deterministic values in unit tests via a
`default_config` fixture instead of relying on whatever the host .env
provides, and remove the env-var coupling from the budget-default tests
by unsetting the keys before resolving the descriptor.

Fix the integration coordinator fixture and test_it005_concurrent_identical_requests
to keep the patch(...) context active for the entire test body — the
previous form exited the `with` block before `resolve_single` ran, so the
service read the unpatched live config at runtime.
test: decouple resolution coordinator tests from .env
…rsions

chore: pin dependency versions to exact values
…-index

docs: add missing ERS_SUBSCRIBER_READY_TIMEOUT to configuration reference
…nual

docs: add ERSys installation guide (ERS1-225)
@gkostkowski gkostkowski requested a review from costezki May 15, 2026 19:27
@costezki costezki merged commit bbc5ed6 into OP-TED:develop May 15, 2026
2 checks passed
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.

5 participants