code.vegaprotocol.io/vega@v0.79.0/libs/net/pipe/pipe.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package pipe
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"net"
    22  
    23  	"google.golang.org/grpc"
    24  )
    25  
    26  type Pipe struct {
    27  	ch   chan net.Conn
    28  	addr Addr
    29  }
    30  
    31  func NewPipe(name string) *Pipe {
    32  	return &Pipe{
    33  		ch:   make(chan net.Conn),
    34  		addr: Addr{name: name},
    35  	}
    36  }
    37  
    38  func (p *Pipe) Accept() (net.Conn, error) {
    39  	conn, ok := <-p.ch
    40  	if !ok {
    41  		return nil, fmt.Errorf("connection channel unexpectedly closed")
    42  	}
    43  	return conn, nil
    44  }
    45  
    46  func (p *Pipe) Close() error {
    47  	close(p.ch)
    48  	return nil
    49  }
    50  
    51  func (p *Pipe) Addr() net.Addr {
    52  	return &p.addr
    53  }
    54  
    55  func (p *Pipe) Dial(ctx context.Context, _ string) (net.Conn, error) {
    56  	conn1, conn2 := net.Pipe()
    57  	select {
    58  	case p.ch <- conn1:
    59  		return conn2, nil
    60  	case <-ctx.Done():
    61  		conn1.Close()
    62  		conn2.Close()
    63  		return nil, ctx.Err()
    64  	}
    65  }
    66  
    67  func (p *Pipe) DialGRPC(ctx context.Context, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
    68  	newOpts := make([]grpc.DialOption, 0, len(opts)+1)
    69  	newOpts = append(newOpts, grpc.WithContextDialer(p.Dial))
    70  	newOpts = append(newOpts, opts...)
    71  
    72  	return grpc.DialContext(ctx, p.Addr().String(), newOpts...)
    73  }