Skip to content

Commit

Permalink
define postgres types, cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
matt2e committed Mar 12, 2024
1 parent 0b8b427 commit 84cf1cf
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 75 deletions.
73 changes: 18 additions & 55 deletions backend/controller/dal/dal.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,8 @@ func runnerFromDB(row sql.GetRunnerRow) Runner {
return Runner{}
}

key, err := model.ParseRunnerDBKey(string(row.RunnerKey))
if err != nil {
return Runner{}
}

return Runner{
Key: key,
Key: row.RunnerKey,
Endpoint: row.Endpoint,
State: RunnerState(row.State),
Deployment: deployment,
Expand Down Expand Up @@ -315,13 +310,8 @@ func (d *DAL) GetStatus(
return Runner{}, fmt.Errorf("invalid attributes JSON for runner %s: %w", in.RunnerKey, err)
}

key, err := model.ParseRunnerDBKey(string(in.RunnerKey))
if err != nil {
return Runner{}, fmt.Errorf("invalid id for runner %s: %w", in.RunnerKey, err)
}

return Runner{
Key: key,
Key: in.RunnerKey,
Endpoint: in.Endpoint,
State: RunnerState(in.State),
Deployment: deployment,
Expand All @@ -345,13 +335,9 @@ func (d *DAL) GetStatus(
}
}),
Routes: slices.Map(routes, func(row sql.GetRoutingTableRow) Route {
key, err := model.ParseRunnerDBKey(string(row.RunnerKey))
if err != nil {
return Route{}
}
return Route{
Module: row.ModuleName.MustGet(),
Runner: key,
Runner: row.RunnerKey,
Deployment: row.DeploymentName,
Endpoint: row.Endpoint,
}
Expand All @@ -371,13 +357,8 @@ func (d *DAL) GetRunnersForDeployment(ctx context.Context, deployment model.Depl
return nil, fmt.Errorf("invalid attributes JSON for runner %d: %w", row.ID, err)
}

key, err := model.ParseRunnerDBKey(string(row.Key))
if err != nil {
return nil, fmt.Errorf("invalid id for runner %d: %w", row.ID, err)
}

runners = append(runners, Runner{
Key: key,
Key: row.Key,
Endpoint: row.Endpoint,
State: RunnerState(row.State),
Deployment: optional.Some(deployment),
Expand Down Expand Up @@ -596,17 +577,12 @@ func (d *DAL) ReserveRunnerForDeployment(ctx context.Context, deployment model.D
cancel()
return nil, fmt.Errorf("failed to JSON decode labels for runner %d: %w", runner.ID, err)
}
key, err := model.ParseRunnerDBKey(string(runner.Key))
if err != nil {
cancel()
return nil, fmt.Errorf("invalid id for runner %d: %w", runner.ID, err)
}

return &postgresClaim{
cancel: cancel,
tx: tx,
runner: Runner{
Key: key,
Key: runner.Key,
Endpoint: runner.Endpoint,
State: RunnerState(runner.State),
Deployment: optional.Some(deployment),
Expand Down Expand Up @@ -794,12 +770,9 @@ func (d *DAL) GetProcessList(ctx context.Context) ([]Process, error) {
if err := json.Unmarshal(row.RunnerLabels, &labels); err != nil {
return Process{}, fmt.Errorf("invalid labels JSON for runner %s: %w", row.RunnerKey, err)
}
key, err := model.ParseRunnerDBKey(string(row.RunnerKey.MustGet()))
if err != nil {
return Process{}, fmt.Errorf("invalid runner key %s: %w", row.RunnerKey, err)
}

runner = optional.Some(ProcessRunner{
Key: key,
Key: row.RunnerKey.MustGet(),
Endpoint: endpoint,
Labels: labels,
})
Expand Down Expand Up @@ -844,12 +817,9 @@ func (d *DAL) GetIdleRunners(ctx context.Context, limit int, labels model.Labels
if err != nil {
return Runner{}, fmt.Errorf("%s: %w", "could not unmarshal labels", err)
}
key, err := model.ParseRunnerDBKey(string(row.Key))
if err != nil {
return Runner{}, fmt.Errorf("%s: %w", "invalid runner key", err)
}

return Runner{
Key: key,
Key: row.Key,
Endpoint: row.Endpoint,
State: RunnerState(row.State),
Labels: labels,
Expand All @@ -871,17 +841,14 @@ func (d *DAL) GetRoutingTable(ctx context.Context, modules []string) (map[string
}
out := make(map[string][]Route, len(routes))
for _, route := range routes {
if runnerKey, err := model.ParseRunnerDBKey(string(route.RunnerKey)); err == nil {

// This is guaranteed to be non-nil by the query, but sqlc doesn't quite understand that.
moduleName := route.ModuleName.MustGet()
out[moduleName] = append(out[moduleName], Route{
Module: moduleName,
Deployment: route.DeploymentName,
Runner: runnerKey,
Endpoint: route.Endpoint,
})
}
// This is guaranteed to be non-nil by the query, but sqlc doesn't quite understand that.
moduleName := route.ModuleName.MustGet()
out[moduleName] = append(out[moduleName], Route{
Module: moduleName,
Deployment: route.DeploymentName,
Runner: route.RunnerKey,
Endpoint: route.Endpoint,
})
}
return out, nil
}
Expand Down Expand Up @@ -965,12 +932,8 @@ func (d *DAL) GetIngressRoutes(ctx context.Context, method string) ([]IngressRou
return nil, ErrNotFound
}
return slices.Map(routes, func(row sql.GetIngressRoutesRow) IngressRoute {
key, err := model.ParseRunnerDBKey(string(row.RunnerKey))
if err != nil {
return IngressRoute{}
}
return IngressRoute{
Runner: key,
Runner: row.RunnerKey,
Deployment: row.DeploymentName,
Endpoint: row.Endpoint,
Path: row.Path,
Expand Down
2 changes: 1 addition & 1 deletion backend/controller/sql/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions backend/controller/sql/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions backend/controller/sql/schema/001_init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ CREATE TABLE modules
-- Proto-encoded module schema.
CREATE DOMAIN module_schema_pb AS BYTEA;

CREATE DOMAIN runner_key AS varchar;
CREATE DOMAIN controller_key AS varchar;

CREATE TABLE deployments
(
id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
Expand Down Expand Up @@ -101,7 +104,7 @@ CREATE TABLE runners
(
id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-- Unique identifier for this runner, generated at startup.
key varchar UNIQUE NOT NULL,
key runner_key UNIQUE NOT NULL,
created TIMESTAMPTZ NOT NULL DEFAULT (NOW() AT TIME ZONE 'utc'),
last_seen TIMESTAMPTZ NOT NULL DEFAULT (NOW() AT TIME ZONE 'utc'),
-- If the runner is reserved, this is the time at which the reservation expires.
Expand Down Expand Up @@ -209,7 +212,7 @@ CREATE TYPE controller_state AS ENUM (
CREATE TABLE controller
(
id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
key varchar UNIQUE NOT NULL,
key controller_key UNIQUE NOT NULL,
created TIMESTAMPTZ NOT NULL DEFAULT (NOW() AT TIME ZONE 'utc'),
last_seen TIMESTAMPTZ NOT NULL DEFAULT (NOW() AT TIME ZONE 'utc'),
state controller_state NOT NULL DEFAULT 'live',
Expand Down
7 changes: 7 additions & 0 deletions backend/controller/sql/types.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package sql

import (
"database/sql"
"database/sql/driver"
"time"

"github.com/TBD54566975/ftl/internal/model"
"github.com/alecthomas/types/optional"
)

type NullTime = optional.Option[time.Time]
type NullDuration = optional.Option[time.Duration]
type NullRunnerKey = optional.Option[model.RunnerKey]

var _ sql.Scanner = (*NullRunnerKey)(nil)
var _ driver.Valuer = (*NullRunnerKey)(nil)
22 changes: 13 additions & 9 deletions internal/model/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,49 @@
package model

import (
"crypto/rand"
"database/sql"
"database/sql/driver"
"fmt"
"math/rand"
"math/big"
"reflect"
"strconv"
"strings"
)

func NewRunnerKey(hostname string, port string) RunnerKey {
suffix, err := rand.Int(rand.Reader, big.NewInt(10000))
if err != nil {
panic(err)
}
return keyType[runnerKey]{
Hostname: hostname,
Port: port,
Suffix: rand.Intn(10000),
Suffix: int(suffix.Int64()),
}
}
func NewLocalRunnerKey(suffix int) RunnerKey {
return keyType[runnerKey]{
Suffix: suffix,
}
}
func ParseRunnerKey(key string) (RunnerKey, error) { return parseKey[RunnerKey](key, true) }
func ParseRunnerDBKey(key string) (RunnerKey, error) { return parseKey[RunnerKey](key, false) }
func ParseRunnerKey(key string) (RunnerKey, error) { return parseKey[RunnerKey](key, true) }

type runnerKey struct{}
type RunnerKey = keyType[runnerKey]

func NewControllerKey(hostname string, port string) ControllerKey {
suffix, err := rand.Int(rand.Reader, big.NewInt(10000))
if err != nil {
panic(err)
}
return keyType[controllerKey]{
Hostname: hostname,
Port: port,
Suffix: rand.Intn(10000),
Suffix: int(suffix.Int64()),
}
}
func ParseControllerKey(key string) (ControllerKey, error) { return parseKey[ControllerKey](key, true) }
func ParseControllerDBKey(key string) (ControllerKey, error) {
return parseKey[ControllerKey](key, false)
}

type controllerKey struct{}
type ControllerKey = keyType[controllerKey]
Expand Down Expand Up @@ -142,7 +147,6 @@ func (d keyType[T]) string(includeKind bool) string {

func (d keyType[T]) MarshalText() ([]byte, error) { return []byte(d.String()), nil }
func (d *keyType[T]) UnmarshalText(bytes []byte) error {
fmt.Printf("marshal text: %s\n", string(bytes))
id, err := parseKey[keyType[T]](string(bytes), true)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion internal/model/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestRunnerKey(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, test.key, parsed, "expected %v for %v after parsing", test.key, parsed)

parsed, err = ParseRunnerDBKey(value)
parsed, err = parseKey[RunnerKey](value, false)
assert.NoError(t, err)
assert.Equal(t, test.key, parsed, "expected %v for %v after parsing db key", test.key, parsed)
}
Expand Down
8 changes: 8 additions & 0 deletions sqlc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ sql:
- db_type: "pg_catalog.varchar"
nullable: true
go_type: "github.com/alecthomas/types/optional.Option[string]"
- db_type: "runner_key"
go_type: "github.com/TBD54566975/ftl/internal/model.RunnerKey"
- db_type: "runner_key"
nullable: true
go_type:
type: "NullRunnerKey"
- db_type: "controller_key"
go_type: "github.com/TBD54566975/ftl/internal/model.ControllerKey"
- db_type: "text"
go_type: "string"
- db_type: "text"
Expand Down

0 comments on commit 84cf1cf

Please sign in to comment.