func (h *transportHandle) ServiceGenerator() ServiceGenerator { if !h.Running.Load() { panic(fmt.Sprintf("handle for plugin %q has already been closed", h.name)) } if _, hasFeature := h.Features[api.FeatureServiceGenerator]; !hasFeature { return nil } return &serviceGenerator{ handle: h, Running: h.Running, ServiceGenerator: api.NewServiceGeneratorClient(multiplex.NewClient( "ServiceGenerator", envelope.NewClient(_proto, h.Transport), )), } }
func fakeEnvelopeClient() (envelope.Client, func()) { in, out, done := fakeStreams() return envelope.NewClient(_proto, frame.NewClient(in, out)), done }
// NewTransportHandle builds a new Handle which speaks to the given transport. // // If the transport is an io.Closer, it will be closed when the handle is closed. func NewTransportHandle(name string, t envelope.Transport) (Handle, error) { client := api.NewPluginClient(multiplex.NewClient( "Plugin", envelope.NewClient(_proto, t), )) handshake, err := client.Handshake(&api.HandshakeRequest{}) if err != nil { return nil, errHandshakeFailed{Name: name, Reason: err} } if handshake.Name != name { return nil, errHandshakeFailed{ Name: name, Reason: errNameMismatch{Want: name, Got: handshake.Name}, } } if handshake.APIVersion != api.APIVersion { return nil, errHandshakeFailed{ Name: name, Reason: errAPIVersionMismatch{Want: api.APIVersion, Got: handshake.APIVersion}, } } // If we got here, the API version matches so the plugin must have // provided the Version if handshake.LibraryVersion == nil { return nil, errHandshakeFailed{ Name: name, Reason: errVersionIsRequired, } } version, err := semver.Parse(*handshake.LibraryVersion) if err != nil { return nil, errHandshakeFailed{Name: name, Reason: err} } if !compatRange.Contains(version) { return nil, errHandshakeFailed{ Name: name, Reason: errVersionMismatch{ Want: compatRange, Got: *handshake.LibraryVersion, }, } } features := make(map[api.Feature]struct{}, len(handshake.Features)) for _, feature := range handshake.Features { features[feature] = struct{}{} } return &transportHandle{ name: name, Transport: t, Client: client, Running: atomic.NewBool(true), Features: features, }, nil }