github.com/demonoid81/containerd@v1.3.4/pkg/ttrpcutil/client.go (about) 1 /* 2 Copyright The containerd Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package ttrpcutil 18 19 import ( 20 "sync" 21 "time" 22 23 v1 "github.com/containerd/containerd/api/services/ttrpc/events/v1" 24 "github.com/containerd/ttrpc" 25 "github.com/pkg/errors" 26 ) 27 28 const ttrpcDialTimeout = 5 * time.Second 29 30 type ttrpcConnector func() (*ttrpc.Client, error) 31 32 // Client is the client to interact with TTRPC part of containerd server (plugins, events) 33 type Client struct { 34 mu sync.Mutex 35 connector ttrpcConnector 36 client *ttrpc.Client 37 closed bool 38 } 39 40 // NewClient returns a new containerd TTRPC client that is connected to the containerd instance provided by address 41 func NewClient(address string, opts ...ttrpc.ClientOpts) (*Client, error) { 42 connector := func() (*ttrpc.Client, error) { 43 conn, err := ttrpcDial(address, ttrpcDialTimeout) 44 if err != nil { 45 return nil, errors.Wrap(err, "failed to connect") 46 } 47 48 client := ttrpc.NewClient(conn, opts...) 49 return client, nil 50 } 51 52 client, err := connector() 53 if err != nil { 54 return nil, err 55 } 56 57 return &Client{ 58 connector: connector, 59 client: client, 60 }, nil 61 } 62 63 // Reconnect re-establishes the TTRPC connection to the containerd daemon 64 func (c *Client) Reconnect() error { 65 c.mu.Lock() 66 defer c.mu.Unlock() 67 68 if c.connector == nil { 69 return errors.New("unable to reconnect to containerd, no connector available") 70 } 71 72 if c.closed { 73 return errors.New("client is closed") 74 } 75 76 client, err := c.connector() 77 if err != nil { 78 return err 79 } 80 81 c.client = client 82 return nil 83 } 84 85 // EventsService creates an EventsService client 86 func (c *Client) EventsService() v1.EventsService { 87 return v1.NewEventsClient(c.Client()) 88 } 89 90 // Client returns the underlying TTRPC client object 91 func (c *Client) Client() *ttrpc.Client { 92 c.mu.Lock() 93 defer c.mu.Unlock() 94 95 return c.client 96 } 97 98 // Close closes the clients TTRPC connection to containerd 99 func (c *Client) Close() error { 100 c.mu.Lock() 101 defer c.mu.Unlock() 102 103 c.closed = true 104 return c.client.Close() 105 }