@@ -19,9 +19,8 @@ package contextfn
1919import (
2020 "context"
2121 "encoding/json"
22+ "fmt"
2223 "net"
23- "os"
24- "path/filepath"
2524 "sync"
2625 "time"
2726
@@ -37,16 +36,10 @@ import (
3736
3837// Handle is the owner of a running in-process context function.
3938type Handle struct {
40- // Target is the gRPC target that dials the function. Set this as the
41- // FunctionInput address passed to the render engine.
42- Target string
43-
39+ target string
4440 srv * grpc.Server
4541 fn * server
46- socketPath string
47- dir string
4842 stop sync.Once
49- log logging.Logger
5043 seedInput * runtime.RawExtension
5144 captureInput * runtime.RawExtension
5245}
@@ -58,9 +51,8 @@ func (h *Handle) Captured() *structpb.Struct {
5851}
5952
6053// Start starts an in-process gRPC server that implements the composition
61- // function RunFunction RPC for context seeding and capture. The server
62- // listens on a unix-domain socket inside a fresh temp directory. Callers
63- // must call Handle.Stop when done.
54+ // function RunFunction RPC for context seeding and capture. Callers must call
55+ // Handle.Stop when done.
6456func Start (ctx context.Context , log logging.Logger , contextData map [string ]any ) (* Handle , error ) {
6557 si , err := json .Marshal (input {Mode : modeSeed })
6658 if err != nil {
@@ -71,51 +63,24 @@ func Start(ctx context.Context, log logging.Logger, contextData map[string]any)
7163 return nil , errors .Wrap (err , "cannot create capture context function input" )
7264 }
7365
74- dir , err := os .MkdirTemp ("" , "render-ctx-*" )
75- if err != nil {
76- return nil , errors .Wrap (err , "cannot create temp dir for context function socket" )
77- }
78-
79- cleanup := func () {
80- _ = os .RemoveAll (dir )
81- }
82-
83- sockPath := filepath .Join (dir , "s" )
8466 var lc net.ListenConfig
85- lis , err := lc .Listen (ctx , "unix " , sockPath )
67+ lis , err := lc .Listen (ctx , "tcp " , ":0" )
8668 if err != nil {
87- cleanup ()
88- return nil , errors .Wrapf (err , "cannot listen on %q" , sockPath )
89- }
90-
91- cleanup = func () {
92- _ = lis .Close ()
93- _ = os .RemoveAll (dir )
94- }
95-
96- // In order for processes in Docker containers to connect to the socket, the
97- // socket must be world-writeable and its containing directory must be
98- // world-readable.
99- if err := os .Chmod (dir , 0o755 ); err != nil { //nolint:gosec // Necessary.
100- cleanup ()
101- return nil , errors .Wrapf (err , "cannot make socket directory world-readable" )
102- }
103- if err := os .Chmod (sockPath , 0o777 ); err != nil { //nolint:gosec // Necessary.
104- cleanup ()
105- return nil , errors .Wrapf (err , "cannot make socket file writeable" )
69+ return nil , errors .Wrap (err , "cannot create listener for context function" )
10670 }
10771
10872 srv := grpc .NewServer (grpc .Creds (insecure .NewCredentials ()))
10973 fn := newServer (contextData )
11074 fnv1 .RegisterFunctionRunnerServiceServer (srv , fn )
11175
76+ addr := lis .Addr ().(* net.TCPAddr ) //nolint:forcetypeassert // We specified "tcp" above.
77+
11278 h := & Handle {
113- Target : "unix://" + sockPath ,
79+ // Report the target as 127.0.0.1:PORT since the render machinery knows
80+ // how to handle functions listening on loopback.
81+ target : fmt .Sprintf ("127.0.0.1:%d" , addr .Port ),
11482 srv : srv ,
11583 fn : fn ,
116- socketPath : sockPath ,
117- dir : dir ,
118- log : log ,
11984 seedInput : & runtime.RawExtension {Raw : si },
12085 captureInput : & runtime.RawExtension {Raw : ci },
12186 }
@@ -129,8 +94,8 @@ func Start(ctx context.Context, log logging.Logger, contextData map[string]any)
12994 return h , nil
13095}
13196
132- // Stop gracefully stops the function server and removes the socket directory.
133- // Safe to call multiple times.
97+ // Stop gracefully stops the function server, which closes its listener. Safe to
98+ // call multiple times.
13499func (h * Handle ) Stop () {
135100 h .stop .Do (func () {
136101 done := make (chan struct {})
@@ -143,8 +108,5 @@ func (h *Handle) Stop() {
143108 case <- time .After (5 * time .Second ):
144109 h .srv .Stop ()
145110 }
146- if err := os .RemoveAll (h .dir ); err != nil {
147- h .log .Debug ("Cannot remove context function socket directory" , "dir" , h .dir , "error" , err )
148- }
149111 })
150112}
0 commit comments