Basic streaming plugin support (#31940)

This pull request migrates testdata to coreplugin streaming capabilities,
this is mostly a working concept of streaming plugins at the moment, 
the work will continue in the following pull requests.
This commit is contained in:
Alexander Emelin
2021-03-23 20:24:08 +03:00
committed by GitHub
parent 1cd8981be4
commit 336bc559a3
31 changed files with 1204 additions and 290 deletions

View File

@ -23,6 +23,7 @@ type clientV2 struct {
grpcplugin.DiagnosticsClient
grpcplugin.ResourceClient
grpcplugin.DataClient
grpcplugin.StreamClient
pluginextensionv2.RendererPlugin
}
@ -42,6 +43,11 @@ func newClientV2(descriptor PluginDescriptor, logger log.Logger, rpcClient plugi
return nil, err
}
rawStream, err := rpcClient.Dispense("stream")
if err != nil {
return nil, err
}
rawRenderer, err := rpcClient.Dispense("renderer")
if err != nil {
return nil, err
@ -66,6 +72,12 @@ func newClientV2(descriptor PluginDescriptor, logger log.Logger, rpcClient plugi
}
}
if rawStream != nil {
if plugin, ok := rawStream.(grpcplugin.StreamClient); ok {
c.StreamClient = plugin
}
}
if rawRenderer != nil {
if plugin, ok := rawRenderer.(pluginextensionv2.RendererPlugin); ok {
c.RendererPlugin = plugin
@ -76,6 +88,7 @@ func newClientV2(descriptor PluginDescriptor, logger log.Logger, rpcClient plugi
client := &Client{
DataPlugin: c.DataClient,
RendererPlugin: c.RendererPlugin,
StreamClient: c.StreamClient,
}
if err := descriptor.startFns.OnStart(descriptor.pluginID, client, logger); err != nil {
return nil, err
@ -158,6 +171,48 @@ func (c *clientV2) CallResource(ctx context.Context, req *backend.CallResourceRe
}
}
func (c *clientV2) CanSubscribeToStream(ctx context.Context, req *backend.SubscribeToStreamRequest) (*backend.SubscribeToStreamResponse, error) {
if c.StreamClient == nil {
return nil, backendplugin.ErrMethodNotImplemented
}
protoResp, err := c.StreamClient.CanSubscribeToStream(ctx, backend.ToProto().SubscribeToStreamRequest(req))
if err != nil {
return nil, err
}
return backend.FromProto().SubscribeToStreamResponse(protoResp), nil
}
func (c *clientV2) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender backend.StreamPacketSender) error {
if c.StreamClient == nil {
return backendplugin.ErrMethodNotImplemented
}
protoReq := backend.ToProto().RunStreamRequest(req)
protoStream, err := c.StreamClient.RunStream(ctx, protoReq)
if err != nil {
if status.Code(err) == codes.Unimplemented {
return backendplugin.ErrMethodNotImplemented
}
return errutil.Wrap("Failed to call resource", err)
}
for {
protoResp, err := protoStream.Recv()
if err != nil {
if status.Code(err) == codes.Unimplemented {
return backendplugin.ErrMethodNotImplemented
}
if errors.Is(err, io.EOF) {
return nil
}
return errutil.Wrap("failed to receive call resource response", err)
}
if err := sender.Send(backend.FromProto().StreamPacket(protoResp)); err != nil {
return err
}
}
}
type dataClientQueryDataFunc func(ctx context.Context, req *pluginv2.QueryDataRequest, opts ...grpc.CallOption) (*pluginv2.QueryDataResponse, error)
func (fn dataClientQueryDataFunc) QueryData(ctx context.Context, req *pluginv2.QueryDataRequest, opts ...grpc.CallOption) (*pluginv2.QueryDataResponse, error) {