Skip to content

Add asynchronous support to handlers and KE requests#35

Open
DaviddeBest-TNO wants to merge 10 commits into
mainfrom
27-to-async
Open

Add asynchronous support to handlers and KE requests#35
DaviddeBest-TNO wants to merge 10 commits into
mainfrom
27-to-async

Conversation

@DaviddeBest-TNO
Copy link
Copy Markdown
Contributor

This adds full async support to the knowledge mapper, including:

  • REACT and ANSWER handlers can be defined as async or sync according to user needs, and are executed either async or in a new thread respectively.
  • The whole app lifetime is ran in a asyncio event loop allowing for all interactions to be handled async.
  • The KE client is replaced with a fully async one, switch to httpx from requests.
  • Dependencies can also be resolved async
  • Number of concurrent handlers is limited by a semaphore with a default of max 10.

DaviddeBest-TNO and others added 10 commits May 27, 2026 16:52
- Replace requests with httpx in pyproject.toml dependencies
- Add pytest-asyncio as dev dependency with asyncio_mode=auto
- Make all ClientProtocol methods async def
- Migrate Client to httpx.AsyncClient for all HTTP calls
- Add close() method to ClientProtocol and both implementations
- Migrate TestClient to async, replace deque with asyncio.Queue
- Make KnowledgeBase lifecycle/interaction methods async
- Extract _register_ki_locally() for sync decorator registration
- Migrate all tests to async and verify passing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- resolve_dependencies() is now async def
- Async Depends factories (async def) are detected via
  asyncio.iscoroutinefunction() and awaited
- Sync Depends factories (def) continue to work without changes
- Nested/transitive resolution works when mixing sync and async factories
- dependency_overrides works with async replacement factories
- Caching semantics (cache=True/False) preserved for both sync and async
- dispatch() and call() updated to async to propagate the change
- All DI tests updated to async and passing
- Added 6 new tests for async factory behaviors
- Updated CONTEXT.md to reflect async factory support

Closes #29

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- dispatch() detects async handlers via asyncio.iscoroutinefunction()
  and awaits them directly; sync handlers run via asyncio.to_thread()
- Handler type alias accepts both sync and async callables
- Decorator wrapper (_register_ki_decorator) preserves async-ness of
  the original handler function
- answer_ki/react_ki decorators remain synchronous (registration only)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add async close() method to KnowledgeBase, delegates to client.close()
- Update example tests (07-testing) to use async/await for KB methods
- Make example kb.py functions async (ask_for_values_of_subject, repeat_value_post)
- Add test_close_delegates_to_client to test_kb_lifespan.py
- Update CONTEXT.md lifecycle and outgoing interaction docs with await syntax

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Redesign start_handling_loop() to dispatch multiple handler invocations
concurrently, bounded by a configurable semaphore.

- Add max_concurrent_handlers parameter (default 10)
- Each poll-dispatch cycle acquires the semaphore, polls, and on HANDLE
  spawns an asyncio.Task that runs the handler, posts the response, and
  releases the semaphore
- Handler exceptions are caught: error is logged and empty binding set
  posted back to the SC
- On EXIT signal, loop stops polling and awaits all in-flight tasks
- Store running event loop reference (self._loop) on KnowledgeBase
- loops parameter preserved for testing

Tests:
- Concurrent dispatch (two slow handlers overlap in time)
- Error handling (handler throws, empty BS posted, loop continues)
- Graceful shutdown (EXIT awaits in-flight handlers)
- Semaphore bounding (max_concurrent_handlers respected)
- Event loop stored on KB instance

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@DaviddeBest-TNO
Copy link
Copy Markdown
Contributor Author

@Sophietje
Ik realiseer me dat deze PR een beetje een draak om te reviewen is, maar het omzetten naar async handlers en HTTP requests moest een beetje in 1 keer gebeuren.
Ik ben vooral beniewd in de review van wat je vindt van hoe de examples nu zijn en of dit een nette manier is om mensen KB's te laten bouwen.
Voor welke stappen er zijn gezet in deze PR kun je even in de gelinkte issues kijken.
Heb het wel gecode samen met een agent maar steeds in relatief kleine stappen en dat gereviewed, lijkt goed te zijn gekomen :).

@DaviddeBest-TNO DaviddeBest-TNO marked this pull request as ready for review May 28, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment