Skip to content

Commit

Permalink
add a lookup for workers (#141)
Browse files Browse the repository at this point in the history
* add a lookup for workers

* add a deserialize method for text id strings

* LOL worked on my machine
  • Loading branch information
DoctorVin authored Jun 26, 2023
1 parent 9941b77 commit e8bdb6e
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 0 deletions.
19 changes: 19 additions & 0 deletions events/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (

ErrRegistryUninitialized = errors.New("controller registry uninitialized")
ErrRegistryPreviouslyInitialized = errors.New("controller registry previously initialized")
ErrBadRegistryData = errors.New("bad registry data")
)

func InitializeActiveControllerRegistry(njs *events.NatsJetstream) error {
Expand Down Expand Up @@ -91,3 +92,21 @@ func DeregisterController(id ControllerID) error {
}
return registry.Delete(id.String())
}

func LastContact(id ControllerID) (time.Time, error) {
var zt time.Time
if registry == nil {
return zt, ErrRegistryUninitialized
}
entry, err := registry.Get(id.String())
if err != nil {
return zt, err // this can either be a communication error or nats.ErrKeyNotFound
}
// if we have an entry the controller was alive in the last TTL period
var ar activityRecord
err = json.Unmarshal(entry.Value(), &ar)
if err != nil {
return zt, ErrBadRegistryData // consumers should *probably* treat this as a success?
}
return ar.LastActive, nil
}
9 changes: 9 additions & 0 deletions events/registry/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package registry
import (
"testing"

"github.com/nats-io/nats.go"
"github.com/stretchr/testify/require"

"go.hollow.sh/toolbox/events"
Expand All @@ -24,6 +25,9 @@ func TestAppLifecycle(t *testing.T) {
err = DeregisterController(id)
require.Error(t, err)
require.Equal(t, ErrRegistryUninitialized, err)
_, err = LastContact(id)
require.Error(t, err)
require.Equal(t, ErrRegistryUninitialized, err)

//OK, now let's get serious
srv := kvTest.StartJetStreamServer(t)
Expand All @@ -43,6 +47,11 @@ func TestAppLifecycle(t *testing.T) {
require.NoError(t, err)
err = ControllerCheckin(id)
require.NoError(t, err)
_, err = LastContact(id)
require.NoError(t, err)
err = DeregisterController(id)
require.NoError(t, err)
_, err = LastContact(id)
require.Error(t, err)
require.ErrorIs(t, err, nats.ErrKeyNotFound)
}
22 changes: 22 additions & 0 deletions events/registry/types.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
// nolint: wsl // it's useless
package registry

import (
"errors"
"fmt"
"strings"
"time"

"github.com/google/uuid"
)

var (
ErrBadFormat = errors.New("bad worker id format")
)

type ControllerID interface {
fmt.Stringer
updateVersion(uint64)
Expand All @@ -23,6 +30,21 @@ func (id *workerUUID) String() string {
return id.appName + "/" + id.uuid.String()
}

func ControllerIDFromString(s string) (ControllerID, error) {
name, uuidStr, found := strings.Cut(s, "/")
if !found {
return nil, fmt.Errorf("%w: missing delimiter", ErrBadFormat)
}
uuid, err := uuid.Parse(uuidStr)
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrBadFormat, err.Error())
}
return &workerUUID{
appName: name,
uuid: uuid,
}, nil
}

func (id *workerUUID) updateVersion(rev uint64) {
id.kvVersion = rev
}
Expand Down
15 changes: 15 additions & 0 deletions events/registry/types_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//nolint:all // it's a test
package registry

import (
"testing"

"github.com/google/uuid"
"github.com/stretchr/testify/require"
)

Expand All @@ -14,4 +16,17 @@ func TestWorkerID(t *testing.T) {
id2 := GetID("myAppName")
require.NotNil(t, id2)
require.NotEqual(t, id.String(), id2.String())

idStr := id.String()

reconstituted, err := ControllerIDFromString(idStr)
require.NoError(t, err)
require.Equal(t, id.(*workerUUID).appName, reconstituted.(*workerUUID).appName)
require.Equal(t, id.(*workerUUID).uuid, reconstituted.(*workerUUID).uuid)

_, err = ControllerIDFromString(uuid.New().String())
require.ErrorIs(t, err, ErrBadFormat, "no slash in name")

_, err = ControllerIDFromString("app-name/bogus")
require.ErrorIs(t, err, ErrBadFormat, "bogus uuid")
}

0 comments on commit e8bdb6e

Please sign in to comment.