Files
coder/provisionersdk/transport.go
T

81 lines
1.8 KiB
Go

package provisionersdk
import (
"context"
"io"
"net"
"github.com/hashicorp/yamux"
"storj.io/drpc"
"storj.io/drpc/drpcconn"
)
const (
// MaxMessageSize is the maximum payload size that can be
// transported without error.
MaxMessageSize = 4 << 20
)
// TransportPipe creates an in-memory pipe for dRPC transport.
func TransportPipe() (*yamux.Session, *yamux.Session) {
c1, c2 := net.Pipe()
yamuxConfig := yamux.DefaultConfig()
yamuxConfig.LogOutput = io.Discard
client, err := yamux.Client(c1, yamuxConfig)
if err != nil {
panic(err)
}
server, err := yamux.Server(c2, yamuxConfig)
if err != nil {
panic(err)
}
return client, server
}
// Conn returns a multiplexed dRPC connection from a yamux session.
func Conn(session *yamux.Session) drpc.Conn {
return &multiplexedDRPC{session}
}
// Allows concurrent requests on a single dRPC connection.
// Required for calling functions concurrently.
type multiplexedDRPC struct {
session *yamux.Session
}
func (m *multiplexedDRPC) Close() error {
return m.session.Close()
}
func (m *multiplexedDRPC) Closed() <-chan struct{} {
return m.session.CloseChan()
}
func (m *multiplexedDRPC) Invoke(ctx context.Context, rpc string, enc drpc.Encoding, inMessage, outMessage drpc.Message) error {
conn, err := m.session.Open()
if err != nil {
return err
}
dConn := drpcconn.New(conn)
defer func() {
_ = dConn.Close()
}()
return dConn.Invoke(ctx, rpc, enc, inMessage, outMessage)
}
func (m *multiplexedDRPC) NewStream(ctx context.Context, rpc string, enc drpc.Encoding) (drpc.Stream, error) {
conn, err := m.session.Open()
if err != nil {
return nil, err
}
dConn := drpcconn.New(conn)
stream, err := dConn.NewStream(ctx, rpc, enc)
if err == nil {
go func() {
<-stream.Context().Done()
_ = dConn.Close()
}()
}
return stream, err
}