about summary refs log tree commit diff
path: root/third_party/overlays/patches/cbtemulator-uds.patch
commit 1397e10225d8c6fd079a86fccd58fb5d0f4200bc
Author: Florian Klink <flokli@flokli.de>
Date:   Fri Mar 29 10:06:34 2024 +0100

    feat(bigtable/emulator): allow listening on Unix Domain Sockets
    
    cbtemulator listening on unix domain sockets is much easier than trying
    to allocate free TCP ports, especially if many cbtemulators are run at
    the same time in integration tests.
    
    This adds an additional flag, address, which has priority if it's set,
    rather than host:port.
    
    `NewServer` already takes a `laddr string`, so we simply check for it to
    contain slashes, and if so, listen on unix, rather than TCP.

diff --git a/bigtable/bttest/inmem.go b/bigtable/bttest/inmem.go
index 556abc2a85..33e4bf2667 100644
--- a/bttest/inmem.go
+++ b/bttest/inmem.go
@@ -40,6 +40,7 @@ import (
 	"math"
 	"math/rand"
 	"net"
+	"os"
 	"regexp"
 	"sort"
 	"strings"
@@ -106,7 +107,15 @@ type server struct {
 // The Server will be listening for gRPC connections, without TLS,
 // on the provided address. The resolved address is named by the Addr field.
 func NewServer(laddr string, opt ...grpc.ServerOption) (*Server, error) {
-	l, err := net.Listen("tcp", laddr)
+	var l net.Listener
+	var err error
+
+	// If the address contains slashes, listen on a unix domain socket instead.
+	if strings.Contains(laddr, "/") {
+		l, err = net.Listen("unix", laddr)
+	} else {
+		l, err = net.Listen("tcp", laddr)
+	}
 	if err != nil {
 		return nil, err
 	}
diff --git a/bigtable/cmd/emulator/cbtemulator.go b/bigtable/cmd/emulator/cbtemulator.go
index 144c09ffb1..deaf69b717 100644
--- a/cmd/emulator/cbtemulator.go
+++ b/cmd/emulator/cbtemulator.go
@@ -27,8 +27,9 @@ import (
 )
 
 var (
-	host = flag.String("host", "localhost", "the address to bind to on the local machine")
-	port = flag.Int("port", 9000, "the port number to bind to on the local machine")
+	host    = flag.String("host", "localhost", "the address to bind to on the local machine")
+	port    = flag.Int("port", 9000, "the port number to bind to on the local machine")
+	address = flag.String("address", "", "address:port number or unix socket path to listen on. Has priority over host/port")
 )
 
 const (
@@ -42,7 +43,15 @@ func main() {
 		grpc.MaxRecvMsgSize(maxMsgSize),
 		grpc.MaxSendMsgSize(maxMsgSize),
 	}
-	srv, err := bttest.NewServer(fmt.Sprintf("%s:%d", *host, *port), opts...)
+
+	var laddr string
+	if *address != "" {
+		laddr = *address
+	} else {
+		laddr = fmt.Sprintf("%s:%d", *host, *port)
+	}
+
+	srv, err := bttest.NewServer(laddr, opts...)
 	if err != nil {
 		log.Fatalf("failed to start emulator: %v", err)
 	}
commit ce16f843d6c93159d86b3807c6d9ff66e43aac67
Author: Florian Klink <flokli@flokli.de>
Date:   Fri Mar 29 11:53:15 2024 +0100

    feat(bigtable): clean up unix socket on close
    
    Call srv.Close when receiving an interrupt, and delete the unix domain
    socket in that function.

diff --git a/bigtable/bttest/inmem.go b/bigtable/bttest/inmem.go
index 33e4bf2667..0dc96024b1 100644
--- a/bttest/inmem.go
+++ b/bttest/inmem.go
@@ -148,6 +148,11 @@ func (s *Server) Close() {
 
 	s.srv.Stop()
 	s.l.Close()
+
+	// clean up unix socket
+	if strings.Contains(s.Addr, "/") {
+		_ = os.Remove(s.Addr)
+	}
 }
 
 func (s *server) CreateTable(ctx context.Context, req *btapb.CreateTableRequest) (*btapb.Table, error) {
diff --git a/bigtable/cmd/emulator/cbtemulator.go b/bigtable/cmd/emulator/cbtemulator.go
index deaf69b717..5a9e8f7a8c 100644
--- a/cmd/emulator/cbtemulator.go
+++ b/cmd/emulator/cbtemulator.go
@@ -18,9 +18,12 @@ cbtemulator launches the in-memory Cloud Bigtable server on the given address.
 package main
 
 import (
+	"context"
 	"flag"
 	"fmt"
 	"log"
+	"os"
+	"os/signal"
 
 	"cloud.google.com/go/bigtable/bttest"
 	"google.golang.org/grpc"
@@ -51,11 +54,18 @@ func main() {
 		laddr = fmt.Sprintf("%s:%d", *host, *port)
 	}
 
+	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
+	defer stop()
+
 	srv, err := bttest.NewServer(laddr, opts...)
 	if err != nil {
 		log.Fatalf("failed to start emulator: %v", err)
 	}
 
 	fmt.Printf("Cloud Bigtable emulator running on %s\n", srv.Addr)
-	select {}
+	select {
+	case <-ctx.Done():
+		srv.Close()
+		stop()
+	}
 }