Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
14f5452
Added the previously lost HintSessionBalancer
kprokopenko Jun 19, 2025
cb58117
CHANGELOG update
kprokopenko Jun 19, 2025
b422c24
Added closing close hint check
kprokopenko Jun 19, 2025
fa92f3b
Merge pull request #1814 from ydb-platform/bug_HintSessionBalancer_maybe
kprokopenko Jun 19, 2025
8cc56e1
Apply suggestions from code review
kprokopenko Jun 20, 2025
e31a3a7
Added support for HintSessionBalancer for the native driver
kprokopenko Jun 24, 2025
e9b4755
Fixed the test description
kprokopenko Jun 24, 2025
6da8e80
The `ydb.WithDisableServerBalancer` option can now work with the nati…
kprokopenko Jun 25, 2025
ca2ac92
The name has been corrected: WithDisableServerBalancer -> WithDisable…
kprokopenko Jun 25, 2025
2bfc4da
Fixed DisableSessionBalancer docstring
kprokopenko Jun 25, 2025
ef7b9f8
Merge branch 'master' into bug_HintSessionBalancer
kprokopenko Jun 25, 2025
b88eb65
linter issues have been fixed
kprokopenko Jun 25, 2025
3b15ca5
Merge branch 'master' into bug_HintSessionBalancer
kprokopenko Jun 27, 2025
057daf7
Refactoring
kprokopenko Jun 27, 2025
1a0a274
Refactoring
kprokopenko Jun 30, 2025
fe6d0cb
Refactoring
kprokopenko Jun 30, 2025
3a0c69f
Merge branch 'master' into bug_HintSessionBalancer
kprokopenko Jun 30, 2025
015ed17
Merge
kprokopenko Jun 30, 2025
e9aa5c7
Changelog fix
kprokopenko Jun 30, 2025
8e53f4d
fixes from review
kprokopenko Jun 30, 2025
b1f0a58
fixes from code review
kprokopenko Jun 30, 2025
f552fc9
fixes from code review
kprokopenko Jun 30, 2025
17c9565
fixes from review
kprokopenko Jun 30, 2025
bf615eb
fixes from review
kprokopenko Jun 30, 2025
736011e
Update CHANGELOG.md
asmyasnikov Jul 1, 2025
a1bc738
Update CHANGELOG.md
asmyasnikov Jul 1, 2025
7f4005f
Update CHANGELOG.md
asmyasnikov Jul 1, 2025
aa0745d
switch ydb-slo-action to main branch in slo-reports
kprokopenko Jul 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/slo-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
if: github.event.workflow_run.conclusion == 'success'
steps:
- name: Publish YDB SLO Report
uses: ydb-platform/ydb-slo-action/report@charts
uses: ydb-platform/ydb-slo-action/report@main
with:
github_run_id: ${{ github.event.workflow_run.id }}
github_token: ${{ secrets.GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
* Fixed the support of server-side session balancing in `database/sql` driver
* Added `ydb.WithDisableSessionBalancer()` driver option for disable server-side session balancing on table and query clients

## v3.111.3
* Fixed session closing in `ydb.WithExecuteDataQueryOverQueryClient(true)` scenario

Expand Down
10 changes: 10 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type Common struct {
traceRetry trace.Retry
retryBudget budget.Budget

disableSessionBalancer bool

panicCallback func(e interface{})
}

Expand Down Expand Up @@ -60,6 +62,10 @@ func (c *Common) RetryBudget() budget.Budget {
return c.retryBudget
}

func (c *Common) DisableSessionBalancer() bool {
return c.disableSessionBalancer
}

// SetOperationTimeout define the maximum amount of time a YDB server will process
// an operation. After timeout exceeds YDB will try to cancel operation and
// regardless of the cancellation appropriate error will be returned to
Expand Down Expand Up @@ -97,3 +103,7 @@ func SetTraceRetry(c *Common, t *trace.Retry, opts ...trace.RetryComposeOption)
func SetRetryBudget(c *Common, b budget.Budget) {
c.retryBudget = b
}

func (c *Common) SetDisableSessionBalancer() {
c.disableSessionBalancer = true
}
5 changes: 5 additions & 0 deletions internal/query/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"google.golang.org/grpc"

"github.com/ydb-platform/ydb-go-sdk/v3/internal/closer"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/meta"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/operation"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/pool"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/query/config"
Expand Down Expand Up @@ -595,6 +596,10 @@ func New(ctx context.Context, cc grpc.ClientConnInterface, cfg *config.Config) *
}
defer cancelCreate()

if !cfg.DisableSessionBalancer() {
createCtx = meta.WithAllowFeatures(createCtx, meta.HintSessionBalancer)
}

s, err := createSession(createCtx, client,
WithConn(cc),
WithDeleteTimeout(cfg.SessionDeleteTimeout()),
Expand Down
6 changes: 6 additions & 0 deletions internal/query/config/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,9 @@ func WithLazyTx(lazyTx bool) Option {
c.lazyTx = lazyTx
}
}

func WithDisableSessionBalancer() Option {
return func(c *Config) {
c.SetDisableSessionBalancer()
}
}
17 changes: 16 additions & 1 deletion internal/query/session_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import (
"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Query"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"

"github.com/ydb-platform/ydb-go-sdk/v3/internal/closer"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/conn"
balancerContext "github.com/ydb-platform/ydb-go-sdk/v3/internal/endpoint"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/meta"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/pool"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/stack"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/xcontext"
Expand Down Expand Up @@ -90,6 +92,19 @@ func (core *sessionCore) Status() string {
}
}

func (core *sessionCore) checkCloseHint(md metadata.MD) {
for header, values := range md {
if header != meta.HeaderServerHints {
continue
}
for _, hint := range values {
if hint == meta.HintSessionClose {
core.SetStatus(StatusClosing)
}
}
}
}

type Option func(*sessionCore)

func WithConn(cc grpc.ClientConnInterface) Option {
Expand Down Expand Up @@ -150,7 +165,7 @@ func Open(
if core.cc != nil {
core.Client = Ydb_Query_V1.NewQueryServiceClient(
conn.WithContextModifier(core.cc, func(ctx context.Context) context.Context {
return balancerContext.WithNodeID(ctx, core.NodeID())
return meta.WithTrailerCallback(balancerContext.WithNodeID(ctx, core.NodeID()), core.checkCloseHint)
}),
)
}
Expand Down
5 changes: 5 additions & 0 deletions internal/table/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"

"github.com/ydb-platform/ydb-go-sdk/v3/internal/meta"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/pool"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/stack"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/table/config"
Expand Down Expand Up @@ -56,6 +57,10 @@ func New(ctx context.Context, cc grpc.ClientConnInterface, config *config.Config
}),
pool.WithClock[*Session, Session](config.Clock()),
pool.WithCreateItemFunc[*Session, Session](func(ctx context.Context) (*Session, error) {
if !config.DisableSessionBalancer() {
ctx = meta.WithAllowFeatures(ctx, meta.HintSessionBalancer)
}

return newSession(ctx, cc, config)
}),
pool.WithTrace[*Session, Session](&pool.Trace{
Expand Down
6 changes: 6 additions & 0 deletions internal/table/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ func UseQuerySession(b bool) Option {
}
}

func WithDisableSessionBalancer() Option {
return func(c *Config) {
c.SetDisableSessionBalancer()
}
}

// WithClock replaces default clock
func WithClock(clock clockwork.Clock) Option {
return func(c *Config) {
Expand Down
5 changes: 5 additions & 0 deletions internal/xsql/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"google.golang.org/grpc"

"github.com/ydb-platform/ydb-go-sdk/v3/internal/bind"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/meta"
internalQuery "github.com/ydb-platform/ydb-go-sdk/v3/internal/query"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/query/config"
"github.com/ydb-platform/ydb-go-sdk/v3/internal/stack"
Expand Down Expand Up @@ -117,6 +118,10 @@ func (c *Connector) Connect(ctx context.Context) (_ driver.Conn, finalErr error)
stack.FunctionID("database/sql.(*Connector).Connect", stack.Package("database/sql")),
)

if !c.disableServerBalancer {
ctx = meta.WithAllowFeatures(ctx, meta.HintSessionBalancer)
}

switch c.processor {
case QUERY:
s, err := internalQuery.CreateSession(ctx, Ydb_Query_V1.NewQueryServiceClient(c.balancer), c.queryConfig)
Expand Down
14 changes: 14 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,20 @@ func WithDatabase(database string) Option {
}
}

// WithDisableSessionBalancer returns an Option that disables session balancing.
func WithDisableSessionBalancer() Option {
return func(ctx context.Context, d *Driver) error {
d.queryOptions = append(d.queryOptions, queryConfig.WithDisableSessionBalancer())
d.tableOptions = append(d.tableOptions, tableConfig.WithDisableSessionBalancer())

// implicit disable session balancer for SQL driver;
// rule of thumb: if user disables session balancer anywhere, we disable it everywhere
d.databaseSQLOptions = append(d.databaseSQLOptions, WithDisableServerBalancer())

return nil
}
}

// WithSecure defines secure option
//
// Warning: use ydb.Open with required Driver string parameter instead
Expand Down
53 changes: 32 additions & 21 deletions tests/integration/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,39 +127,50 @@ func (scope *scopeT) driverNamed(name string, opts ...ydb.Option) *ydb.Driver {
connectionString := scope.ConnectionString()
scope.Logf("Connect with connection string, driver name %q: %v", name, connectionString)

token := scope.AuthToken()
if token == "" {
scope.Logf("With empty auth token")
opts = append(opts, ydb.WithAnonymousCredentials())
} else {
scope.Logf("With auth token")
opts = append(opts, ydb.WithAccessTokenCredentials(token))
}
cert := scope.CertFile()
if cert == "" {
scope.Logf("Without tls")
opts = append(opts, ydb.WithTLSSInsecureSkipVerify())
} else {
scope.Logf("With tls")
opts = append(opts, ydb.WithCertificatesFromFile(cert))
}
driver := scope.NonCachingDriver(opts...)

connectionContext, cancel := context.WithTimeout(scope.Ctx, time.Second*10)
defer cancel()

driver, err := ydb.Open(connectionContext, connectionString, opts...)
clean := func() {
if driver != nil {
scope.Require.NoError(driver.Close(scope.Ctx))
}
}

return fixenv.NewGenericResultWithCleanup(driver, clean), err
return fixenv.NewGenericResultWithCleanup(driver, clean), nil
}

return fixenv.CacheResult(scope.Env, f, fixenv.CacheOptions{CacheKey: name})
}

func (scope *scopeT) NonCachingDriver(opts ...ydb.Option) *ydb.Driver {
connectionString := scope.ConnectionString()
scope.Logf("Connect with connection string: %v", connectionString)

token := scope.AuthToken()
if token == "" {
scope.Logf("With empty auth token")
opts = append(opts, ydb.WithAnonymousCredentials())
} else {
scope.Logf("With auth token")
opts = append(opts, ydb.WithAccessTokenCredentials(token))
}
cert := scope.CertFile()
if cert == "" {
scope.Logf("Without tls")
opts = append(opts, ydb.WithTLSSInsecureSkipVerify())
} else {
scope.Logf("With tls")
opts = append(opts, ydb.WithCertificatesFromFile(cert))
}

connectionContext, cancel := context.WithTimeout(scope.Ctx, time.Second*10)
defer cancel()

driver, err := ydb.Open(connectionContext, connectionString, opts...)
scope.Require.NoError(err)

return driver
}

func (scope *scopeT) SQLDriver(opts ...ydb.ConnectorOption) *sql.DB {
f := func() (*fixenv.GenericResult[*sql.DB], error) {
driver := scope.Driver()
Expand Down
Loading
Loading