Skip to content

extend session events to cover raw connections and commands - #498

Open
SergeiPavlov wants to merge 5 commits into
master-servicetitanfrom
async-events
Open

extend session events to cover raw connections and commands#498
SergeiPavlov wants to merge 5 commits into
master-servicetitanfrom
async-events

Conversation

@SergeiPavlov

@SergeiPavlov SergeiPavlov commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Recreating of #493
@dagreen-st Please dont merge it until testing with the Monolith

Summary

  • Adds a DbConnectionOpened event on SessionEventAccessor, fired once per genuine Closed→Open connection transition
  • Adds an internal EventNotifyingDbCommand wrapper so DirectSqlAccessor.CreateCommand() raises the same DbCommandExecuting/DbCommandExecuted events the ORM's own commands do
  • Adds GetConnectionAsync on IDirectSqlService/DirectSqlAccessor, backed by the existing async prepare path, plus an awaitable raw-connection-accessed hook

Related:

Test plan

  • dotnet build on Xtensive.Orm and Xtensive.Orm.Tests
  • New tests (DbConnectionOpenedEventTest, EventNotifyingDbCommandTest, DirectSqlGetConnectionAsyncTest) pass against a local SQL Server container
  • Full Xtensive.Orm.Tests.Storage suite run before/after: identical pre-existing failures, no regressions

Reapplies #493, which was reverted after merge (commits 8e9144d and 1f127aa).

Discussion: https://servicetitan.enterprise.slack.com/archives/C0BP3S50BGQ and on the original PR #493

The ORM's own DbCommandExecuting/Executed events only fire for
commands run through its own execution path, and there was no hook
for a connection's first genuine open or for a raw connection handed
out without a DbCommand. Code using DirectSqlAccessor, or needing the
raw connection directly, had no way to observe any of this.

Adds a DbConnectionOpened event fired on the Closed to Open
transition, an EventNotifyingDbCommand wrapper so
DirectSqlAccessor.CreateCommand() raises the same execute events ORM
commands do, and an async GetConnectionAsync with an awaitable
raw-connection-accessed hook so callers that need the connection
itself can hook in without blocking a thread.
@SergeiPavlov SergeiPavlov changed the title Async events extend session events to cover raw connections and commands Aug 5, 2026
TagOpenConnection/TagOpenConnectionAsync create their own command on
the raw connection, but if that connection has a pending local
transaction, SqlClient requires the command's Transaction be set or
it throws instead of tagging. GetConnectionAsync's caller has no way
to supply it. Adds Transaction to DbConnectionEventArgs and threads
DirectSqlAccessor's already-tracked active transaction through both
raw-connection-accessed hooks, so ITenantConnectionTagger consumers
can set it on their own command.
@dagreen-st

Copy link
Copy Markdown
Collaborator

previously approved on #493, running some manual tests before merge

Raises a session event before a connection's init SQL runs so a subscriber
can append to that batch (e.g. USE [db]; SET CONTEXT_INFO ...) instead of
paying a separate round-trip. Appending here takes effect before the first
command runs on the connection.

Fires on the same closed-to-open transition as DbConnectionOpened, before
the open, on both sync and async paths.
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.

3 participants