mirror of https://github.com/coder/coder.git
74 lines
1.4 KiB
Go
74 lines
1.4 KiB
Go
package tailnet
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"cdr.dev/slog"
|
|
"github.com/coder/coder/v2/coderd/database/pubsub"
|
|
)
|
|
|
|
type readyForHandshake struct {
|
|
src uuid.UUID
|
|
dst uuid.UUID
|
|
}
|
|
|
|
type handshaker struct {
|
|
ctx context.Context
|
|
logger slog.Logger
|
|
coordinatorID uuid.UUID
|
|
pubsub pubsub.Pubsub
|
|
updates <-chan readyForHandshake
|
|
|
|
workerWG sync.WaitGroup
|
|
}
|
|
|
|
func newHandshaker(ctx context.Context,
|
|
logger slog.Logger,
|
|
id uuid.UUID,
|
|
ps pubsub.Pubsub,
|
|
updates <-chan readyForHandshake,
|
|
startWorkers <-chan struct{},
|
|
) *handshaker {
|
|
s := &handshaker{
|
|
ctx: ctx,
|
|
logger: logger,
|
|
coordinatorID: id,
|
|
pubsub: ps,
|
|
updates: updates,
|
|
}
|
|
// add to the waitgroup immediately to avoid any races waiting for it before
|
|
// the workers start.
|
|
s.workerWG.Add(numHandshakerWorkers)
|
|
go func() {
|
|
<-startWorkers
|
|
for i := 0; i < numHandshakerWorkers; i++ {
|
|
go s.worker()
|
|
}
|
|
}()
|
|
return s
|
|
}
|
|
|
|
func (t *handshaker) worker() {
|
|
defer t.workerWG.Done()
|
|
|
|
for {
|
|
select {
|
|
case <-t.ctx.Done():
|
|
t.logger.Debug(t.ctx, "handshaker worker exiting", slog.Error(t.ctx.Err()))
|
|
return
|
|
|
|
case rfh := <-t.updates:
|
|
err := t.pubsub.Publish(eventReadyForHandshake, []byte(fmt.Sprintf(
|
|
"%s,%s", rfh.dst.String(), rfh.src.String(),
|
|
)))
|
|
if err != nil {
|
|
t.logger.Error(t.ctx, "publish ready for handshake", slog.Error(err))
|
|
}
|
|
}
|
|
}
|
|
}
|