// Variables for interactive containers, these have very specialized use-cases (e.g. debugging) // and shouldn't be used for general purpose containers.
// Whether this container should allocate a buffer for stdin in the container runtime. If this // is not set, reads from stdin in the container will always result in EOF. // Default is false. // +optional Stdin bool`json:"stdin,omitempty" protobuf:"varint,16,opt,name=stdin"` // Whether the container runtime should close the stdin channel after it has been opened by // a single attach. When stdin is true the stdin stream will remain open across multiple attach // sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the // first client attaches to stdin, and then remains open and accepts data until the client disconnects, // at which time stdin is closed and remains closed until the container is restarted. If this // flag is false, a container processes that reads from stdin will never receive an EOF. // Default is false // +optional StdinOnce bool`json:"stdinOnce,omitempty" protobuf:"varint,17,opt,name=stdinOnce"` // Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. // Default is false. // +optional TTY bool`json:"tty,omitempty" protobuf:"varint,18,opt,name=tty"`
sql/driver 中定义了 db driver 应实现的接口,其中明确了 ErrBadConn 的处理方式
The Connector.Connect and Driver.Open methods should never return ErrBadConn.
ErrBadConn should only be returned from Validator, SessionResetter, or a query method if the connection is already in an invalid (e.g. closed) state.
var ErrBadConn = errors.New("driver: bad connection")
ErrBadConn should be returned by a driver to signal to the sql package that a driver.Conn is in a bad state (such as the server having earlier closed the connection) and the sql package should retry on a new connection.
To prevent duplicate operations, ErrBadConn should NOT be returned if there’s a possibility that the database server might have performed the operation. Even if the server sends back an error, you shouldn’t return ErrBadConn.
// maxBadConnRetries is the number of maximum retries if the driver returns // driver.ErrBadConn to signal a broken connection before forcing a new // connection to be opened. const maxBadConnRetries = 2
// QueryContext executes a query that returns rows, typically a SELECT. // The args are for any placeholder parameters in the query. func(db *DB)QueryContext(ctx context.Context, query string, args ...interface{})(*Rows, error) { var rows *Rows var err error for i := 0; i < maxBadConnRetries; i++ { rows, err = db.query(ctx, query, args, cachedOrNewConn) if err != driver.ErrBadConn { break } } if err == driver.ErrBadConn { return db.query(ctx, query, args, alwaysNewConn) } return rows, err }
// Query executes a query that returns rows, typically a SELECT. // The args are for any placeholder parameters in the query. func(db *DB)Query(query string, args ...interface{})(*Rows, error) { return db.QueryContext(context.Background(), query, args...) }
// ExecContext executes a query without returning any rows. // The args are for any placeholder parameters in the query. func(db *DB)ExecContext(ctx context.Context, query string, args ...interface{})(Result, error) { var res Result var err error for i := 0; i < maxBadConnRetries; i++ { res, err = db.exec(ctx, query, args, cachedOrNewConn) if err != driver.ErrBadConn { break } } if err == driver.ErrBadConn { return db.exec(ctx, query, args, alwaysNewConn) } return res, err }
// Exec executes a query without returning any rows. // The args are for any placeholder parameters in the query. func(db *DB)Exec(query string, args ...interface{})(Result, error) { return db.ExecContext(context.Background(), query, args...) }
综上 ErrBadConn 时,最多重试 2 次,使用 cached conn 或 new conn;超过重试次数,再尝试使用 new conn 1 次
A Context is safe for simultaneous use by multiple goroutines. Code can pass a single Context to any number of goroutines and cancel that Context to signal all of them.
var rootCmd = &cobra.Command{ Use: "long run cli", Run: func(cmd *cobra.Command, args []string) { cli := run.New() err := cli.LongRun(cmd.Context())
if err != nil { fmt.Printf("cli run err: %v\n", err) if exitError, ok := err.(*exec.ExitError); ok { fmt.Printf("exit code: %d\n", exitError.ExitCode()) } } }, }
graph LR
InitContainer --> TrainingContainer
InitContainer --> SidecarContainer
InitContainer and SidecarContainer act like system container and they are transparent to the TrainingContainer
TrainingJob(process) of user is running at TrainingContainer
we can do the init env action at InitContainer, such as download data, and the upload action can be done at SidecarContainer
however, there will be an engineering problem, that is, the file read permission problem. The best way is to make the InitC / SidecarC / TrainingC users (uid) the same