Skip to content

Commit c7dce81

Browse files
committed
bugfix: schema is reset after a reconnect
We need to keep an existing schema resolver to avoid a schema reset after a reconnect. An another approach could be to get a schema on each reconnect, but we will change the expected behavior in this case: load a schema once on a first connect.
1 parent 10b3c8f commit c7dce81

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
1414

1515
### Fixed
1616

17+
- `unable to use an index name because schema is not loaded` error after
18+
a reconnect (#424).
19+
1720
## [v2.2.0] - 2024-12-16
1821

1922
The release introduces the IPROTO_INSERT_ARROW request (arrow.InsertRequest)

connection.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -446,12 +446,13 @@ func (conn *Connection) dial(ctx context.Context) error {
446446
conn.Greeting.Salt = connGreeting.Salt
447447
conn.serverProtocolInfo = c.ProtocolInfo()
448448

449-
spaceAndIndexNamesSupported :=
450-
isFeatureInSlice(iproto.IPROTO_FEATURE_SPACE_AND_INDEX_NAMES,
449+
if conn.schemaResolver == nil {
450+
namesSupported := isFeatureInSlice(iproto.IPROTO_FEATURE_SPACE_AND_INDEX_NAMES,
451451
conn.serverProtocolInfo.Features)
452452

453-
conn.schemaResolver = &noSchemaResolver{
454-
SpaceAndIndexNamesSupported: spaceAndIndexNamesSupported,
453+
conn.schemaResolver = &noSchemaResolver{
454+
SpaceAndIndexNamesSupported: namesSupported,
455+
}
455456
}
456457

457458
// Watchers.

tarantool_test.go

+55
Original file line numberDiff line numberDiff line change
@@ -3868,6 +3868,61 @@ func TestWatcher_Unregister_concurrent(t *testing.T) {
38683868
wg.Wait()
38693869
}
38703870

3871+
func TestConnection_named_index_after_reconnect(t *testing.T) {
3872+
const server = "127.0.0.1:3015"
3873+
3874+
testDialer := dialer
3875+
testDialer.Address = server
3876+
3877+
inst, err := test_helpers.StartTarantool(test_helpers.StartOpts{
3878+
Dialer: testDialer,
3879+
InitScript: "config.lua",
3880+
Listen: server,
3881+
WaitStart: 100 * time.Millisecond,
3882+
ConnectRetry: 10,
3883+
RetryTimeout: 500 * time.Millisecond,
3884+
})
3885+
defer test_helpers.StopTarantoolWithCleanup(inst)
3886+
if err != nil {
3887+
t.Fatalf("Unable to start Tarantool: %s", err)
3888+
}
3889+
3890+
reconnectOpts := opts
3891+
reconnectOpts.Reconnect = 100 * time.Millisecond
3892+
reconnectOpts.MaxReconnects = 10
3893+
3894+
conn := test_helpers.ConnectWithValidation(t, testDialer, reconnectOpts)
3895+
defer conn.Close()
3896+
3897+
test_helpers.StopTarantool(inst)
3898+
3899+
request := NewSelectRequest("test").Index("primary").Limit(1)
3900+
_, err = conn.Do(request).Get()
3901+
if err == nil {
3902+
t.Fatalf("An error expected.")
3903+
}
3904+
3905+
if err := test_helpers.RestartTarantool(&inst); err != nil {
3906+
t.Fatalf("Unable to restart Tarantool: %s", err)
3907+
}
3908+
3909+
maxTime := reconnectOpts.Reconnect * time.Duration(reconnectOpts.MaxReconnects)
3910+
timeout := time.After(maxTime)
3911+
3912+
for {
3913+
select {
3914+
case <-timeout:
3915+
t.Fatalf("Failed to execute request without an error, last error: %s", err)
3916+
default:
3917+
}
3918+
3919+
_, err = conn.Do(request).Get()
3920+
if err == nil {
3921+
return
3922+
}
3923+
}
3924+
}
3925+
38713926
func TestConnect_schema_update(t *testing.T) {
38723927
conn := test_helpers.ConnectWithValidation(t, dialer, opts)
38733928
defer conn.Close()

0 commit comments

Comments
 (0)