Replace SessionRow.kernels usages with explicit queries and remove the relationship
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 17h 7m
- Merged PRs (30d)
- 358
Description
Remove the last remaining ORM relationship on the session/kernel side, SessionRow.kernels, and converge the row helpers built on it onto the dataclass-based accessor pattern already used by the sokovan lifecycle view.
### Background
BA-7226 removed 8 of the 9 target relationships. AgentRow.agent_resource_rows, AgentResourceRow.slot_type_row, KernelRow.image_row/agent_row/group_row/user_row, SessionRow.user/group and KernelRow.session are gone; SessionRow.kernels lost its back_populates and is now one-directional. This story covers the remainder, which was split out because it is a consumer-side refactor rather than a relationship removal.
### Target
- SessionRow.kernels - the relationship definition itself.
- SessionRow.main_kernel, resource_opts, get_kernel_by_id, delegate_ownership - row helpers that iterate self.kernels.
- SessionRow.kernel_load_option() - the selectinload/contains_eager factory the helpers are loaded through.
### Scope
Introduce a view type that pairs a session with its kernels, following views/sokovan/lifecycle.py, and move the helpers onto it. Measured consumer counts at the time of writing:
- selectinload(SessionRow.kernels) sites: 22, including filtered eager loads such as selectinload(SessionRow.kernels.and_(KernelRow.cluster_role == DEFAULT_ROLE)), which have no drop-in replacement and need explicit queries plus batched assembly so the conversion does not introduce N+1 queries.
- main_kernel consumers: about 70 - registry.py 29, services/session 22, api/gql_legacy/session.py 9, repositories/session/db_source 6, services/stream 4, bgtask/tasks/commit_session.py 4.
- Test sites referencing main_kernel or SessionRow.kernels: about 30.
gql_legacy is in scope and is converted here rather than deferred to the gql_legacy removal.
### Notes
- KernelLoadingStrategy.MAIN_KERNEL_ONLY currently discards the result of kernel_rel.and_(...) in SessionRow.get_session and list_sessions, so it loads every kernel rather than the main one. Decide the intended behaviour while converting.
- SessionRow.kernels declares no cascade or passive_deletes and nothing writes through the relationship, so delete behaviour is driven by the database foreign keys and is unaffected by the removal.
JIRA Issue: BA-7369
Contributor guide
Research direction
Start by reading views/sokovan/lifecycle.py and the SessionRow helpers listed in the issue, then trace the selectinload(SessionRow.kernels) sites and the main_kernel consumers in registry.py, services/session, api/gql_legacy/session.py, repositories/session/db_source, services/stream, and bgtask/tasks/commit_session.py. Review the roughly 30 affected tests. Done means the helpers use the dataclass-based accessor pattern, explicit queries avoid N+1 loads, and SessionRow.kernels and its loading factory are removed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, sqlalchemy
- Domain
- backend, database
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100