mirror of
https://github.com/cirruslabs/orchard.git
synced 2026-10-18 04:43:12 +02:00
API endpoint and associated RPC changes to resolve VMs IP's (#188)
* API endpoint and associated RPC changes to resolve VMs IP's * Fix "Missing expected argument '<name>'" error when doing "tart set" * Implement TestIPEndpoint() and IP() method in controller HTTP client
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package rendezvous
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/cirruslabs/orchard/internal/concurrentmap"
|
||||
)
|
||||
|
||||
var ErrInvalidToken = errors.New("invalid rendezvous token")
|
||||
|
||||
type Rendezvous[T any] struct {
|
||||
sessions *concurrentmap.ConcurrentMap[*TokenSlot[T]]
|
||||
}
|
||||
|
||||
type TokenSlot[T any] struct {
|
||||
ctx context.Context
|
||||
ch chan T
|
||||
}
|
||||
|
||||
func New[T any]() *Rendezvous[T] {
|
||||
return &Rendezvous[T]{
|
||||
sessions: concurrentmap.NewConcurrentMap[*TokenSlot[T]](),
|
||||
}
|
||||
}
|
||||
|
||||
func (rendezvous *Rendezvous[T]) Request(ctx context.Context, session string) (chan T, func()) {
|
||||
tokenSlot := &TokenSlot[T]{
|
||||
ctx: ctx,
|
||||
ch: make(chan T),
|
||||
}
|
||||
|
||||
rendezvous.sessions.Store(session, tokenSlot)
|
||||
|
||||
return tokenSlot.ch, func() {
|
||||
rendezvous.sessions.Delete(session)
|
||||
}
|
||||
}
|
||||
|
||||
func (rendezvous *Rendezvous[T]) Respond(session string, conn T) (context.Context, error) {
|
||||
tokenSlot, ok := rendezvous.sessions.Load(session)
|
||||
if !ok {
|
||||
return nil, ErrInvalidToken
|
||||
}
|
||||
|
||||
tokenSlot.ch <- conn
|
||||
|
||||
return tokenSlot.ctx, nil
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package rendezvous_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/cirruslabs/orchard/internal/controller/rendezvous"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
"net"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestProxy(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
expectedConn, _ := net.Pipe()
|
||||
|
||||
proxy := rendezvous.New[net.Conn]()
|
||||
|
||||
token := uuid.New().String()
|
||||
|
||||
connCh, cancel := proxy.Request(ctx, token)
|
||||
defer cancel()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
_, err := proxy.Respond(token, expectedConn)
|
||||
require.NoError(t, err)
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
actualConn := <-connCh
|
||||
require.Equal(t, expectedConn, actualConn)
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user