Skip to content

Commit f6bd88b

Browse files
committed
review(sdk): addressed comments
1 parent e0827fa commit f6bd88b

4 files changed

Lines changed: 19 additions & 9 deletions

File tree

internal/ipc/design.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,14 @@ Also connect rpc is part of CNCF ([source](https://www.cncf.io/projects/connect-
6969

7070
Potential drawbacks: Performance
7171

72-
Using [nri/net/multiplex](https://github.com/containerd/nri/tree/main/pkg/net/multiplex) with [ttrpc](https://github.com/containerd/ttrpc) probably would be the most performance optimised solution.
73-
It re-uses one stream over the multiplexed socket per direction and has overhead of the http protocol as protobuf gets streamed directly over the multiplexer.
74-
However, it has stopped evolving and e.g. has not caught up on latest improvements on protobuf.
75-
Another major downside is that it's mainly Go only, i.e., supporting alternative languages for plugins would come at a high cost.
76-
We argue that in our use case, as the networking only happens locally so the overhead of grpc over http and the cost of opening a new yamux stream are negligible.
77-
In addition, the main performance bottleneck will be within the actual plugins, e.g., because authentication needs to happen, disk access or because (slow) external networking access is required.
72+
Using [nri/net/multiplex](https://github.com/containerd/nri/tree/main/pkg/net/multiplex) with [ttrpc](https://github.com/containerd/ttrpc) probably would be the most performant solution.
73+
It re-uses one stream over the multiplexed socket per direction and does not have the overhead of the HTTP protocol as Protobuf gets streamed directly over the multiplexer.
74+
Although lightweight, it has stopped evolving and has not caught up to the latest improvements on Protobuf.
75+
Another major downside is that it's mainly Go only.
76+
Plugins written in a different language would come at a high cost.
77+
78+
We argue that in our use case since the networking only happens locally the overhead of GRPC over HTTP and the cost of opening a new yamux stream per API request are negligible.
79+
In addition, the main performance bottleneck will be within the actual plugins due to IO operations, additional upstream network requests and potentially authentication.
7880

7981
---
8082

internal/ipc/ipc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ func createYamuxedClient(session *yamux.Session) *http.Client {
147147
DialContext: func(context.Context, string, string) (net.Conn, error) {
148148
return session.Open()
149149
},
150+
// We don't want to use http keepalive because
151+
// - we keep re-using the underlying socket anyway
152+
// - it allows clean bookkeeping of yamux session / any yamux session means IPC happening and not stale keepalive connections
153+
// -> we can check for session.NumStreams() on shutdown
150154
DisableKeepAlives: true,
151155
}
152156
return &http.Client{Transport: transport}

pkg/adaptation/plugin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ type plugin struct {
4747
close func() error
4848
}
4949

50-
// newExternalPlugin Create a plugin (stub) for an accepted external plugin connection.
50+
// newExternalPlugin creates a plugin (stub) for an accepted external plugin connection.
5151
func newExternalPlugin(conn net.Conn, v setupValidator) (*plugin, error) {
5252
r, err := setup(conn, v)
5353
if err != nil {

pkg/adaptation/plugin_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,14 @@ func Test_newExternalPlugin(t *testing.T) {
8080
{
8181
name: "create external plugin",
8282
test: func(t *testing.T, l net.Listener, conn net.Conn) {
83+
t.Helper()
8384
m := &mockExternalRuntime{l: l, done: make(chan struct{})}
8485
go m.run()
8586

8687
s, err := p.New(newMockedPlugin(), p.WithPluginName("my-plugin"), p.WithConnection(conn))
8788
require.NoError(t, err)
8889
runErr, cancel := runAsyncWithTimeout(t.Context(), s.Run)
89-
defer cancel()
90+
t.Cleanup(cancel)
9091

9192
runtime, err := m.getRuntime()
9293
assert.NoError(t, err)
@@ -102,13 +103,14 @@ func Test_newExternalPlugin(t *testing.T) {
102103
{
103104
name: "plugin returns error on GetSecret",
104105
test: func(t *testing.T, l net.Listener, conn net.Conn) {
106+
t.Helper()
105107
m := &mockExternalRuntime{l: l, done: make(chan struct{})}
106108
go m.run()
107109

108110
s, err := p.New(newMockedPlugin(WithID("rewrite-id")), p.WithPluginName("my-plugin"), p.WithConnection(conn))
109111
require.NoError(t, err)
110112
runErr, cancel := runAsyncWithTimeout(t.Context(), s.Run)
111-
defer cancel()
113+
t.Cleanup(cancel)
112114

113115
runtime, err := m.getRuntime()
114116
assert.NoError(t, err)
@@ -123,6 +125,7 @@ func Test_newExternalPlugin(t *testing.T) {
123125
{
124126
name: "cancelling plugin.run() shuts down the runtime",
125127
test: func(t *testing.T, l net.Listener, conn net.Conn) {
128+
t.Helper()
126129
m := &mockExternalRuntime{l: l, done: make(chan struct{})}
127130
go m.run()
128131

@@ -149,6 +152,7 @@ func Test_newExternalPlugin(t *testing.T) {
149152
{
150153
name: "plugins with invalid patterns are rejected",
151154
test: func(t *testing.T, l net.Listener, conn net.Conn) {
155+
t.Helper()
152156
doneRuntime := make(chan struct{})
153157
go func() {
154158
conn, err := l.Accept()

0 commit comments

Comments
 (0)