mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
refactor corrosion admin client to establish a connection on every command
This commit is contained in:
+16
-17
@@ -13,19 +13,11 @@ import (
|
|||||||
|
|
||||||
// AdminClient is a client for the Corrosion admin API.
|
// AdminClient is a client for the Corrosion admin API.
|
||||||
type AdminClient struct {
|
type AdminClient struct {
|
||||||
conn net.Conn
|
sockPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAdminClient(sockPath string) (*AdminClient, error) {
|
func NewAdminClient(sockPath string) (*AdminClient, error) {
|
||||||
conn, err := net.Dial("unix", sockPath)
|
return &AdminClient{sockPath: sockPath}, nil
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("connect to admin socket: %w", err)
|
|
||||||
}
|
|
||||||
return &AdminClient{conn: conn}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *AdminClient) Close() error {
|
|
||||||
return c.conn.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
@@ -38,18 +30,25 @@ type Response struct {
|
|||||||
// The channel will be closed after sending the last or error response. The caller must read from the channel until
|
// The channel will be closed after sending the last or error response. The caller must read from the channel until
|
||||||
// it is closed.
|
// it is closed.
|
||||||
func (c *AdminClient) SendCommand(cmd []byte) (<-chan Response, error) {
|
func (c *AdminClient) SendCommand(cmd []byte) (<-chan Response, error) {
|
||||||
if _, err := c.conn.Write(encodeFrame(cmd)); err != nil {
|
conn, err := net.Dial("unix", c.sockPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("connect to admin socket: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = conn.Write(encodeFrame(cmd)); err != nil {
|
||||||
|
conn.Close()
|
||||||
return nil, fmt.Errorf("send command: %w", err)
|
return nil, fmt.Errorf("send command: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch := make(chan Response)
|
ch := make(chan Response)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
r := Response{}
|
r := Response{}
|
||||||
|
|
||||||
data, err := c.readFrame()
|
data, err := readFrame(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Err = err
|
r.Err = err
|
||||||
ch <- r
|
ch <- r
|
||||||
@@ -60,7 +59,6 @@ func (c *AdminClient) SendCommand(cmd []byte) (<-chan Response, error) {
|
|||||||
if err = json.Unmarshal(data, &decoded); err != nil {
|
if err = json.Unmarshal(data, &decoded); err != nil {
|
||||||
r.Err = fmt.Errorf("unmarshal response: %w", err)
|
r.Err = fmt.Errorf("unmarshal response: %w", err)
|
||||||
ch <- r
|
ch <- r
|
||||||
// TODO: should we drain the connection here?
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,17 +100,18 @@ func encodeFrame(data []byte) []byte {
|
|||||||
return encoded
|
return encoded
|
||||||
}
|
}
|
||||||
|
|
||||||
// readFrame reads a length_delimited Tokio frame by extracting the frame data that follows the frame head.
|
// readFrame reads a length_delimited Tokio frame from the connection by extracting the frame data that follows
|
||||||
func (c *AdminClient) readFrame() ([]byte, error) {
|
// the frame head.
|
||||||
|
func readFrame(conn net.Conn) ([]byte, error) {
|
||||||
// Read the frame head (4 bytes).
|
// Read the frame head (4 bytes).
|
||||||
head := make([]byte, 4)
|
head := make([]byte, 4)
|
||||||
if _, err := io.ReadFull(c.conn, head); err != nil {
|
if _, err := io.ReadFull(conn, head); err != nil {
|
||||||
return nil, fmt.Errorf("read frame head: %w", err)
|
return nil, fmt.Errorf("read frame head: %w", err)
|
||||||
}
|
}
|
||||||
// Read the frame data (length specified in the frame head).
|
// Read the frame data (length specified in the frame head).
|
||||||
length := binary.BigEndian.Uint32(head)
|
length := binary.BigEndian.Uint32(head)
|
||||||
data := make([]byte, length)
|
data := make([]byte, length)
|
||||||
if _, err := io.ReadFull(c.conn, data); err != nil {
|
if _, err := io.ReadFull(conn, data); err != nil {
|
||||||
return nil, fmt.Errorf("read frame data: %w", err)
|
return nil, fmt.Errorf("read frame data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user