Skip to content

Commit

Permalink
feat: add conn pool
Browse files Browse the repository at this point in the history
  • Loading branch information
go-compile committed Jul 22, 2023
1 parent 96da60a commit 87f2d5c
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 2 deletions.
28 changes: 27 additions & 1 deletion relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ type Relay struct {
m sync.Mutex

protocolSwitching map[int]string

// connPool contains a list of ACTIVE connections
connPool []net.Conn
}

const (
Expand All @@ -79,7 +82,7 @@ const (

// VERSION uses semantic versioning
// this version number is for the library not the CLI
VERSION = "v1.3.4"
VERSION = "v1.4.0"
)

var (
Expand Down Expand Up @@ -284,3 +287,26 @@ func (r *Relay) Serve(l net.Listener) error {
return ErrUnknownProxyType
}
}

// storeConn places the provided net.Conn into the connPoll.
// To remove this conn from the pool, provide it to popConn()
func (r *Relay) storeConn(conn net.Conn) {
r.m.Lock()
defer r.m.Unlock()

r.connPool = append(r.connPool, conn)
}

// popConn removes the provided connection from the conn pool
func (r *Relay) popConn(conn net.Conn) {
r.m.Lock()
defer r.m.Unlock()

for i := 0; i < len(r.connPool); i++ {
if r.connPool[i] == conn {
// remove conn
r.connPool = append(r.connPool[:i], r.connPool[i+1:]...)
return
}
}
}
113 changes: 113 additions & 0 deletions relay_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package localrelay

import (
"io"
"net"
"sync"
"testing"
"time"
)

func TestConnPoolBasic(t *testing.T) {
conns := []net.Conn{}
connAmount := 50
relay := New("test-relay", "127.0.0.1:23838", "127.0.0.1:23838", io.Discard)

for i := 0; i < connAmount; i++ {
conn := &net.TCPConn{}

conns = append(conns, conn)
relay.storeConn(conn)
}

for i := 0; i < connAmount; i++ {
relay.popConn(conns[i])
}

if len(relay.connPool) != 0 {
t.Fatal("connPool is not empty")
}
}

func TestConnPool(t *testing.T) {
// create channel to receive errors from another goroutine
errCh := make(chan error)
go startTCPServer(errCh)

// wait for error or nil error indicating server launched fine
if err := <-errCh; err != nil {
t.Fatal(err)
}

relay := New("test-relay", "127.0.0.1:23838", "127.0.0.1:23838", io.Discard)

wg := sync.WaitGroup{}

// open 10 conns and append to the conn pool
for i := 0; i < 10; i++ {
wg.Add(1)

conn, err := net.Dial("tcp", "127.0.0.1:23838")
if err != nil {
t.Fatal(err)
}

relay.storeConn(conn)

// handle conn
go func(conn net.Conn, i int) {
for {
time.Sleep(time.Millisecond * (10 * time.Duration(i)))
_, err := conn.Write([]byte("test"))
if err != nil {
relay.popConn(conn)

for _, c := range relay.connPool {
if c == conn {
t.Fatal("correct conn was not removed")
}
}

wg.Done()
return
}
}
}(conn, i)
}

wg.Wait()
}

func startTCPServer(errCh chan error) {
l, err := net.Listen("tcp", ":23838")
if err != nil {
errCh <- err
return
}

errCh <- nil

for {
conn, err := l.Accept()
if err != nil {
continue
}

// handle conn with echo server
go func(conn net.Conn) {
for i := 0; i <= 5; i++ {
buf := make([]byte, 1048)
n, err := conn.Read(buf)
if err != nil {
conn.Close()
return
}

conn.Write(buf[:n])
}

// close conn after 5 messages
conn.Close()
}(conn)
}
}
6 changes: 6 additions & 0 deletions relayfailovertcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,14 @@ func relayFailOverTCP(r *Relay, l net.Listener) error {
}

func handleFailOver(r *Relay, conn net.Conn, network string) {
r.storeConn(conn)

defer func() {
conn.Close()

// remove conn from connPool
r.popConn(conn)

r.Metrics.connections(-1)
}()

Expand Down
1 change: 0 additions & 1 deletion relayhttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ func HandleHTTP(relay *Relay) http.HandlerFunc {
}

func handleHTTP(w http.ResponseWriter, r *http.Request, re *Relay) {

re.Metrics.requests(1)

remoteURL := re.ForwardAddr + r.URL.Path + "?" + r.URL.Query().Encode()
Expand Down
6 changes: 6 additions & 0 deletions relaytcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,14 @@ func relayTCP(r *Relay, l net.Listener) error {
}

func handleConn(r *Relay, conn net.Conn, network string) {
r.storeConn(conn)

defer func() {
conn.Close()

// remove conn from connPool
r.popConn(conn)

r.Metrics.connections(-1)
}()

Expand Down

0 comments on commit 87f2d5c

Please sign in to comment.