mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
81 lines
1.8 KiB
Go
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
|
|
}
|