Possible stuck when we set big timeout
vadimalekseev opened this issue · 0 comments
vadimalekseev commented
Describe the bug
Stuck conn.Do(query)
if we set big timeout through the context.Context
Steps to reproduce
- Create context with big timeout, e.g.:
ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
- Do some invalid request (check my example below)
Expected behaviour
It seems to me that we should immediately get a response from the .Do(query)
function
Code example
package main
import (
"context"
"fmt"
"time"
"github.com/ClickHouse/ch-go"
"github.com/ClickHouse/ch-go/chpool"
"github.com/ClickHouse/ch-go/proto"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
defer cancel()
conn, err := chpool.Dial(ctx, chpool.Options{
ClientOptions: ch.Options{
Address: "127.0.0.1:9001",
},
})
if err != nil {
panic(err)
}
err = conn.Do(ctx, ch.Query{Body: `DROP TABLE IF EXISTS test_table_insert`})
if err != nil {
panic(err)
}
err = conn.Do(ctx, ch.Query{
Body: `CREATE TABLE IF NOT EXISTS test_table_insert
(
level Enum8('error'=1, 'warn'=2, 'info'=3, 'debug'=4)
) ENGINE = Memory;`})
if err != nil {
panic(err)
}
level := new(proto.ColEnum)
err = level.Infer("Enum8('error'=1, 'warn'=2, 'info'=3, 'debug'=4)")
if err != nil {
panic(err)
}
level.Append("unknown level") // ! this level does not exist in the enum
err = conn.Do(ctx, ch.Query{
Body: `INSERT INTO test_table_insert VALUES`,
Input: proto.Input{
{Name: "level", Data: level},
},
}) // lock here for an 1 hour
if err != nil {
panic(err)
}
fmt.Println("done")
}
Some parts of the goroutines dump:
1 @ 0x100a74e14 0x100a41b04 0x100a41674 0x100f64da4 0x100f5c7ec 0x100aa6334
# 0x100f64da3 github.com/ClickHouse/ch-go.(*Client).Do.func5+0x43 /Users/valekseev/go/pkg/mod/github.com/!click!house/ch-go@v0.52.0/query.go:688
# 0x100f5c7eb golang.org/x/sync/errgroup.(*Group).Go.func1+0x5b /Users/valekseev/go/pkg/mod/golang.org/x/sync@v0.0.0-20220923202941-7f9b1623fab7/errgroup/errgroup.go:75
1 @ 0x100a74e14 0x100a6dfd8 0x100aa00d0 0x100ada4e8 0x100adb810 0x100adb801 0x100cb97d8 0x100ccac04 0x100b51020 0x100ed677c 0x100ad56f0 0x100ed685c 0x100ed683d 0x100ed65f4 0x100ed65f5 0x100b76bb0 0x100ed6a48 0x100f5d4b4 0x100f64f40 0x100f5c7ec 0x100aa6334
# 0x100aa00cf internal/poll.runtime_pollWait+0x9f /opt/homebrew/Cellar/go/1.19.2/libexec/src/runtime/netpoll.go:305
# 0x100ada4e7 internal/poll.(*pollDesc).wait+0x27 /opt/homebrew/Cellar/go/1.19.2/libexec/src/internal/poll/fd_poll_runtime.go:84
# 0x100adb80f internal/poll.(*pollDesc).waitRead+0x1df /opt/homebrew/Cellar/go/1.19.2/libexec/src/internal/poll/fd_poll_runtime.go:89
# 0x100adb800 internal/poll.(*FD).Read+0x1d0 /opt/homebrew/Cellar/go/1.19.2/libexec/src/internal/poll/fd_unix.go:167
# 0x100cb97d7 net.(*netFD).Read+0x27 /opt/homebrew/Cellar/go/1.19.2/libexec/src/net/fd_posix.go:55
# 0x100ccac03 net.(*conn).Read+0x33 /opt/homebrew/Cellar/go/1.19.2/libexec/src/net/net.go:183
# 0x100b5101f bufio.(*Reader).Read+0x1df /opt/homebrew/Cellar/go/1.19.2/libexec/src/bufio/bufio.go:237
# 0x100ed677b github.com/ClickHouse/ch-go/proto.(*Reader).Read+0x2b /Users/valekseev/go/pkg/mod/github.com/!click!house/ch-go@v0.52.0/proto/reader.go:53
# 0x100ad56ef io.ReadAtLeast+0x9f /opt/homebrew/Cellar/go/1.19.2/libexec/src/io/io.go:332
# 0x100ed685b io.ReadFull+0x3b /opt/homebrew/Cellar/go/1.19.2/libexec/src/io/io.go:351
# 0x100ed683c github.com/ClickHouse/ch-go/proto.(*Reader).ReadFull+0x1c /Users/valekseev/go/pkg/mod/github.com/!click!house/ch-go@v0.52.0/proto/reader.go:62
# 0x100ed65f3 github.com/ClickHouse/ch-go/proto.(*Reader).readFull+0xb3 /Users/valekseev/go/pkg/mod/github.com/!click!house/ch-go@v0.52.0/proto/reader.go:70
# 0x100ed65f4 github.com/ClickHouse/ch-go/proto.(*Reader).ReadByte+0xb4 /Users/valekseev/go/pkg/mod/github.com/!click!house/ch-go@v0.52.0/proto/reader.go:36
# 0x100b76baf encoding/binary.ReadUvarint+0x7f /opt/homebrew/Cellar/go/1.19.2/libexec/src/encoding/binary/varint.go:133
# 0x100ed6a47 github.com/ClickHouse/ch-go/proto.(*Reader).UVarInt+0x27 /Users/valekseev/go/pkg/mod/github.com/!click!house/ch-go@v0.52.0/proto/reader.go:84
# 0x100f5d4b3 github.com/ClickHouse/ch-go.(*Client).packet+0x113 /Users/valekseev/go/pkg/mod/github.com/!click!house/ch-go@v0.52.0/client.go:224
# 0x100f64f3f github.com/ClickHouse/ch-go.(*Client).Do.func4+0xff /Users/valekseev/go/pkg/mod/github.com/!click!house/ch-go@v0.52.0/query.go:657
# 0x100f5c7eb golang.org/x/sync/errgroup.(*Group).Go.func1+0x5b /Users/valekseev/go/pkg/mod/golang.org/x/sync@v0.0.0-20220923202941-7f9b1623fab7/errgroup/errgroup.go:75
Researching brought me to the function func (c *Client) packet(ctx context.Context) (proto.ServerCode, error)
-- we check and override the default timeout from the context:
deadline := time.Now().Add(defaultTimeout)
if d, ok := ctx.Deadline(); ok {
deadline = d
}
Therefore, we have come out of this function for so long, so the done
(/ch-go@v0.52.0/query.go:688
) channel does not close, so we cannot get an answer.
Configuration
Environment
- Client version: v0.52.0
- Language version: 1.19
ClickHouse server
- ClickHouse Server version: 22.1.3.7