Skip to content

Commit d2952f4

Browse files
committed
bugfix: Connect() panics on schema update
Part of #278
1 parent 4b8254f commit d2952f4

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
2424
- ConnectionPool does not properly handle disconnection with Opts.Reconnect
2525
set (#272)
2626
- Watcher events loss with a small per-request timeout (#284)
27+
- Connect() panics on concurrent schema update (#278)
2728

2829
## [1.10.0] - 2022-12-31
2930

config.lua

+17
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,23 @@ local function push_func(cnt)
181181
end
182182
rawset(_G, 'push_func', push_func)
183183

184+
local function create_spaces()
185+
for i=1,10 do
186+
local s = box.schema.space.create('test' .. tostring(i), {
187+
id = 700 + i,
188+
if_not_exists = true,
189+
})
190+
local idx = s:create_index('test' .. tostring(i) .. 'primary', {
191+
type = 'tree',
192+
parts = {1, 'uint'},
193+
if_not_exists = true
194+
})
195+
idx:drop()
196+
s:drop()
197+
end
198+
end
199+
rawset(_G, 'create_spaces', create_spaces)
200+
184201
local function tarantool_version_at_least(wanted_major, wanted_minor, wanted_patch)
185202
-- https://github.com/tarantool/crud/blob/733528be02c1ffa3dacc12c034ee58c9903127fc/test/helper.lua#L316-L337
186203
local major_minor_patch = _TARANTOOL:split('-', 1)[1]

schema.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,13 @@ func (conn *Connection) loadSchema() (err error) {
325325
return err
326326
}
327327
for _, index := range indexes {
328-
schema.SpacesById[index.SpaceId].IndexesById[index.Id] = index
329-
schema.SpacesById[index.SpaceId].Indexes[index.Name] = index
328+
spaceId := index.SpaceId
329+
if _, ok := schema.SpacesById[spaceId]; ok {
330+
schema.SpacesById[spaceId].IndexesById[index.Id] = index
331+
schema.SpacesById[spaceId].Indexes[index.Name] = index
332+
} else {
333+
return errors.New("concurrent schema update")
334+
}
330335
}
331336

332337
conn.lockShards()

tarantool_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -3894,6 +3894,29 @@ func TestWatcher_Unregister_concurrent(t *testing.T) {
38943894
wg.Wait()
38953895
}
38963896

3897+
func TestConnect_schema_update(t *testing.T) {
3898+
conn := test_helpers.ConnectWithValidation(t, server, opts)
3899+
defer conn.Close()
3900+
3901+
for i := 0; i < 100; i++ {
3902+
fut := conn.Do(NewCallRequest("create_spaces"))
3903+
3904+
if conn, err := Connect(server, opts); err != nil {
3905+
if err.Error() != "concurrent schema update" {
3906+
t.Errorf("unexpected error: %s", err)
3907+
}
3908+
} else if conn == nil {
3909+
t.Errorf("conn is nil")
3910+
} else {
3911+
conn.Close()
3912+
}
3913+
3914+
if _, err := fut.Get(); err != nil {
3915+
t.Errorf("Failed to call create_spaces: %s", err)
3916+
}
3917+
}
3918+
}
3919+
38973920
// runTestMain is a body of TestMain function
38983921
// (see https://pkg.go.dev/testing#hdr-Main).
38993922
// Using defer + os.Exit is not works so TestMain body

0 commit comments

Comments
 (0)