Vineeth/force rollback (#486)

* fix: Explicit Rollback in Transaction

* chore: update tests
This commit is contained in:
Vineeth Voruganti 2026-04-03 11:58:03 -04:00 committed by GitHub
parent 29ff4653e5
commit 302a6808e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 33 additions and 16 deletions

View File

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [3.0.5] - 2026-04-03
### Fixed
- explicit rollback on all transactions to force connection closed
## [3.0.4] - 2026-04-02
### Added

View File

@ -8,7 +8,7 @@
---
![Static Badge](https://img.shields.io/badge/Version-3.0.4-blue)
![Static Badge](https://img.shields.io/badge/Version-3.0.5-blue)
[![PyPI version](https://img.shields.io/pypi/v/honcho-ai.svg)](https://pypi.org/project/honcho-ai/)
[![NPM version](https://img.shields.io/npm/v/@honcho-ai/sdk.svg)](https://npmjs.org/package/@honcho-ai/sdk)
[![Discord](https://img.shields.io/discord/1016845111637839922?style=flat&logo=discord&logoColor=23ffffff&label=Plastic%20Labs&labelColor=235865F2)](https://discord.gg/plasticlabs)

View File

@ -30,7 +30,8 @@ This guide helps you match the right SDK version to your Honcho API version. New
| Honcho API Version | TypeScript SDK | Python SDK |
|-------------------|---------------|------------|
| v3.0.4 (Current) | v2.1.0 | v2.1.0 |
| v3.0.5 (Current) | v2.1.0 | v2.1.0 |
| v3.0.4 | v2.1.0 | v2.1.0 |
| v3.0.3 | v2.1.0 | v2.1.0 |
| v3.0.2 | v2.0.0+ | v2.0.0+ |
| v3.0.1 | v2.0.0+ | v2.0.0+ |

View File

@ -27,7 +27,13 @@ Welcome to the Honcho changelog! This section documents all notable changes to t
### Honcho API and SDK Changelogs
<Tabs>
<Tab title="Honcho API">
<Update label="v3.0.4 (Current)">
<Update label="v3.0.5 (Current)">
### Fixed
- explicit rollback on all transactions to force connection closed
</Update>
<Update label="v3.0.4">
### Added
- JSONB metadata validation enforces 100 key limit and max depth of 5 (#419)

View File

@ -29,7 +29,7 @@
"navigation": {
"versions": [
{
"version": "v3.0.4",
"version": "v3.0.5",
"api": {
"openapi": [
"v3/openapi.json"

View File

@ -1,6 +1,6 @@
[project]
name = "honcho"
version = "3.0.4"
version = "3.0.5"
description = "Honcho Server"
authors = [
{name = "Plastic Labs", email = "hello@plasticlabs.ai"},

View File

@ -26,8 +26,12 @@ async def get_db():
await db.rollback()
raise
finally:
if db.in_transaction():
await db.rollback()
# Always send ROLLBACK unconditionally so the wire-level transaction
# is closed before the TCP connection drops. Supavisor v2 does NOT
# clean up orphaned transactions on client disconnect in transaction-
# pooling mode, so relying on `in_transaction()` (Python-side state)
# can leave the backend pinned with an open BEGIN.
await db.rollback()
await db.close()
@ -57,8 +61,8 @@ async def tracked_db(operation_name: str | None = None):
await db.rollback()
raise
finally:
if db.in_transaction():
await db.rollback()
# Always send ROLLBACK unconditionally — see get_db() comment.
await db.rollback()
await db.close()
if token: # Only reset if we set it
request_context.reset(token)

View File

@ -154,7 +154,7 @@ app = FastAPI(
title="Honcho API",
summary="The Identity Layer for the Agentic World",
description="""Honcho is a platform for giving agents user-centric memory and social cognition.""",
version="3.0.4",
version="3.0.5",
contact={
"name": "Plastic Labs",
"url": "https://honcho.dev",

View File

@ -52,7 +52,7 @@ async def test_get_db_sets_application_name_when_tracing_enabled(
await dep_gen.aclose()
request_context.reset(context_token)
assert fake_db.rollback_calls == 0
assert fake_db.rollback_calls == 1 # unconditional rollback in finally
assert fake_db.close_calls == 1
@ -70,7 +70,7 @@ async def test_get_db_rolls_back_and_closes_when_consumer_raises(
with pytest.raises(RuntimeError, match="boom"):
await dep_gen.athrow(RuntimeError("boom"))
assert fake_db.rollback_calls == 1
assert fake_db.rollback_calls == 2 # once in except, once in finally
assert fake_db.close_calls == 1
@ -99,7 +99,7 @@ async def test_tracked_db_creates_and_resets_task_context(
stmt, params = fake_db.execute_calls[0]
assert "set_config" in str(stmt)
assert params == {"name": "task:cleanup_job:12345678"}
assert fake_db.rollback_calls == 0
assert fake_db.rollback_calls == 1 # unconditional rollback in finally
assert fake_db.close_calls == 1
@ -122,7 +122,7 @@ async def test_tracked_db_preserves_existing_request_context(
stmt, params = fake_db.execute_calls[0]
assert "set_config" in str(stmt)
assert params == {"name": "request:existing"}
assert fake_db.rollback_calls == 0
assert fake_db.rollback_calls == 1 # unconditional rollback in finally
assert fake_db.close_calls == 1
@ -138,7 +138,7 @@ async def test_tracked_db_rolls_back_on_error_and_closes(
async with real_tracked_db("operation"):
raise ValueError("failed operation")
assert fake_db.rollback_calls == 1
assert fake_db.rollback_calls == 2 # once in except, once in finally
assert fake_db.close_calls == 1

View File

@ -1282,7 +1282,7 @@ wheels = [
[[package]]
name = "honcho"
version = "3.0.4"
version = "3.0.5"
source = { virtual = "." }
dependencies = [
{ name = "alembic" },