X Tutup
Skip to content

Commit fc87dce

Browse files
authored
Merge pull request containerd#2149 from crosbymichael/reconnect
Add client.Reconnect API
2 parents 255ad41 + 7b653dc commit fc87dce

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

client.go

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,22 @@ func New(address string, opts ...ClientOpt) (*Client, error) {
9393
grpc.WithStreamInterceptor(stream),
9494
)
9595
}
96-
conn, err := grpc.Dial(dialer.DialAddress(address), gopts...)
96+
connector := func() (*grpc.ClientConn, error) {
97+
conn, err := grpc.Dial(dialer.DialAddress(address), gopts...)
98+
if err != nil {
99+
return nil, errors.Wrapf(err, "failed to dial %q", address)
100+
}
101+
return conn, nil
102+
}
103+
conn, err := connector()
97104
if err != nil {
98-
return nil, errors.Wrapf(err, "failed to dial %q", address)
105+
return nil, err
99106
}
100-
return NewWithConn(conn, opts...)
107+
return &Client{
108+
conn: conn,
109+
connector: connector,
110+
runtime: fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtime.GOOS),
111+
}, nil
101112
}
102113

103114
// NewWithConn returns a new containerd client that is connected to the containerd
@@ -112,8 +123,23 @@ func NewWithConn(conn *grpc.ClientConn, opts ...ClientOpt) (*Client, error) {
112123
// Client is the client to interact with containerd and its various services
113124
// using a uniform interface
114125
type Client struct {
115-
conn *grpc.ClientConn
116-
runtime string
126+
conn *grpc.ClientConn
127+
runtime string
128+
connector func() (*grpc.ClientConn, error)
129+
}
130+
131+
// Reconnect re-establishes the GRPC connection to the containerd daemon
132+
func (c *Client) Reconnect() error {
133+
if c.connector == nil {
134+
return errors.New("unable to reconnect to containerd, no connector available")
135+
}
136+
c.conn.Close()
137+
conn, err := c.connector()
138+
if err != nil {
139+
return err
140+
}
141+
c.conn = conn
142+
return nil
117143
}
118144

119145
// IsServing returns true if the client can successfully connect to the

client_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,37 @@ func TestImagePull(t *testing.T) {
191191
t.Fatal(err)
192192
}
193193
}
194+
195+
func TestClientReconnect(t *testing.T) {
196+
t.Parallel()
197+
198+
ctx, cancel := testContext()
199+
defer cancel()
200+
201+
client, err := newClient(t, address)
202+
if err != nil {
203+
t.Fatal(err)
204+
}
205+
if client == nil {
206+
t.Fatal("New() returned nil client")
207+
}
208+
ok, err := client.IsServing(ctx)
209+
if err != nil {
210+
t.Fatal(err)
211+
}
212+
if !ok {
213+
t.Fatal("containerd is not serving")
214+
}
215+
if err := client.Reconnect(); err != nil {
216+
t.Fatal(err)
217+
}
218+
if ok, err = client.IsServing(ctx); err != nil {
219+
t.Fatal(err)
220+
}
221+
if !ok {
222+
t.Fatal("containerd is not serving")
223+
}
224+
if err := client.Close(); err != nil {
225+
t.Errorf("client closed returned errror %v", err)
226+
}
227+
}

0 commit comments

Comments
 (0)
X Tutup