Faas semi worfking
This commit is contained in:
@ -3,6 +3,7 @@ package postgres
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@ -18,6 +19,55 @@ type executionRepository struct {
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// Helper function to convert time.Duration to PostgreSQL interval
|
||||
func durationToInterval(d time.Duration) interface{} {
|
||||
if d == 0 {
|
||||
return nil
|
||||
}
|
||||
// Convert nanoseconds to PostgreSQL interval format
|
||||
seconds := float64(d) / float64(time.Second)
|
||||
return fmt.Sprintf("%.9f seconds", seconds)
|
||||
}
|
||||
|
||||
// Helper function to convert PostgreSQL interval to time.Duration
|
||||
func intervalToDuration(interval interface{}) (time.Duration, error) {
|
||||
if interval == nil {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
switch v := interval.(type) {
|
||||
case string:
|
||||
if v == "" {
|
||||
return 0, nil
|
||||
}
|
||||
// Try to parse as PostgreSQL interval
|
||||
// For now, we'll use a simple approach - parse common formats
|
||||
duration, err := time.ParseDuration(v)
|
||||
if err == nil {
|
||||
return duration, nil
|
||||
}
|
||||
// Handle PostgreSQL interval format like "00:00:05.123456"
|
||||
var hours, minutes int
|
||||
var seconds float64
|
||||
if n, err := fmt.Sscanf(v, "%d:%d:%f", &hours, &minutes, &seconds); n == 3 && err == nil {
|
||||
return time.Duration(hours)*time.Hour + time.Duration(minutes)*time.Minute + time.Duration(seconds*float64(time.Second)), nil
|
||||
}
|
||||
return 0, fmt.Errorf("unable to parse interval: %s", v)
|
||||
case []byte:
|
||||
return intervalToDuration(string(v))
|
||||
default:
|
||||
return 0, fmt.Errorf("unexpected interval type: %T", interval)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to handle JSON fields
|
||||
func jsonField(data json.RawMessage) interface{} {
|
||||
if len(data) == 0 || data == nil {
|
||||
return "{}" // Return empty JSON string instead of nil or RawMessage
|
||||
}
|
||||
return string(data) // Convert RawMessage to string for database operations
|
||||
}
|
||||
|
||||
func NewExecutionRepository(db *sql.DB, logger *zap.Logger) repository.ExecutionRepository {
|
||||
return &executionRepository{
|
||||
db: db,
|
||||
@ -32,7 +82,7 @@ func (r *executionRepository) Create(ctx context.Context, execution *domain.Func
|
||||
RETURNING created_at`
|
||||
|
||||
err := r.db.QueryRowContext(ctx, query,
|
||||
execution.ID, execution.FunctionID, execution.Status, execution.Input,
|
||||
execution.ID, execution.FunctionID, execution.Status, jsonField(execution.Input),
|
||||
execution.ExecutorID, execution.CreatedAt,
|
||||
).Scan(&execution.CreatedAt)
|
||||
|
||||
@ -51,11 +101,11 @@ func (r *executionRepository) GetByID(ctx context.Context, id uuid.UUID) (*domai
|
||||
FROM executions WHERE id = $1`
|
||||
|
||||
execution := &domain.FunctionExecution{}
|
||||
var durationNanos sql.NullInt64
|
||||
var durationInterval sql.NullString
|
||||
|
||||
err := r.db.QueryRowContext(ctx, query, id).Scan(
|
||||
&execution.ID, &execution.FunctionID, &execution.Status, &execution.Input,
|
||||
&execution.Output, &execution.Error, &durationNanos, &execution.MemoryUsed,
|
||||
&execution.Output, &execution.Error, &durationInterval, &execution.MemoryUsed,
|
||||
&execution.ContainerID, &execution.ExecutorID, &execution.CreatedAt,
|
||||
&execution.StartedAt, &execution.CompletedAt,
|
||||
)
|
||||
@ -68,9 +118,14 @@ func (r *executionRepository) GetByID(ctx context.Context, id uuid.UUID) (*domai
|
||||
return nil, fmt.Errorf("failed to get execution: %w", err)
|
||||
}
|
||||
|
||||
// Convert duration
|
||||
if durationNanos.Valid {
|
||||
execution.Duration = time.Duration(durationNanos.Int64)
|
||||
// Convert duration from PostgreSQL interval
|
||||
if durationInterval.Valid {
|
||||
duration, err := intervalToDuration(durationInterval.String)
|
||||
if err != nil {
|
||||
r.logger.Warn("Failed to parse duration interval", zap.String("interval", durationInterval.String), zap.Error(err))
|
||||
} else {
|
||||
execution.Duration = duration
|
||||
}
|
||||
}
|
||||
|
||||
return execution, nil
|
||||
@ -83,15 +138,9 @@ func (r *executionRepository) Update(ctx context.Context, id uuid.UUID, executio
|
||||
container_id = $7, started_at = $8, completed_at = $9
|
||||
WHERE id = $1`
|
||||
|
||||
var durationNanos sql.NullInt64
|
||||
if execution.Duration > 0 {
|
||||
durationNanos.Int64 = int64(execution.Duration)
|
||||
durationNanos.Valid = true
|
||||
}
|
||||
|
||||
_, err := r.db.ExecContext(ctx, query,
|
||||
id, execution.Status, execution.Output, execution.Error,
|
||||
durationNanos, execution.MemoryUsed, execution.ContainerID,
|
||||
id, execution.Status, jsonField(execution.Output), execution.Error,
|
||||
durationToInterval(execution.Duration), execution.MemoryUsed, execution.ContainerID,
|
||||
execution.StartedAt, execution.CompletedAt,
|
||||
)
|
||||
|
||||
@ -155,11 +204,11 @@ func (r *executionRepository) List(ctx context.Context, functionID *uuid.UUID, l
|
||||
var executions []*domain.FunctionExecution
|
||||
for rows.Next() {
|
||||
execution := &domain.FunctionExecution{}
|
||||
var durationNanos sql.NullInt64
|
||||
var durationInterval sql.NullString
|
||||
|
||||
err := rows.Scan(
|
||||
&execution.ID, &execution.FunctionID, &execution.Status, &execution.Input,
|
||||
&execution.Output, &execution.Error, &durationNanos, &execution.MemoryUsed,
|
||||
&execution.Output, &execution.Error, &durationInterval, &execution.MemoryUsed,
|
||||
&execution.ContainerID, &execution.ExecutorID, &execution.CreatedAt,
|
||||
&execution.StartedAt, &execution.CompletedAt,
|
||||
)
|
||||
@ -169,9 +218,14 @@ func (r *executionRepository) List(ctx context.Context, functionID *uuid.UUID, l
|
||||
return nil, fmt.Errorf("failed to scan execution: %w", err)
|
||||
}
|
||||
|
||||
// Convert duration
|
||||
if durationNanos.Valid {
|
||||
execution.Duration = time.Duration(durationNanos.Int64)
|
||||
// Convert duration from PostgreSQL interval
|
||||
if durationInterval.Valid {
|
||||
duration, err := intervalToDuration(durationInterval.String)
|
||||
if err != nil {
|
||||
r.logger.Warn("Failed to parse duration interval", zap.String("interval", durationInterval.String), zap.Error(err))
|
||||
} else {
|
||||
execution.Duration = duration
|
||||
}
|
||||
}
|
||||
|
||||
executions = append(executions, execution)
|
||||
@ -205,11 +259,11 @@ func (r *executionRepository) GetByStatus(ctx context.Context, status domain.Exe
|
||||
var executions []*domain.FunctionExecution
|
||||
for rows.Next() {
|
||||
execution := &domain.FunctionExecution{}
|
||||
var durationNanos sql.NullInt64
|
||||
var durationInterval sql.NullString
|
||||
|
||||
err := rows.Scan(
|
||||
&execution.ID, &execution.FunctionID, &execution.Status, &execution.Input,
|
||||
&execution.Output, &execution.Error, &durationNanos, &execution.MemoryUsed,
|
||||
&execution.Output, &execution.Error, &durationInterval, &execution.MemoryUsed,
|
||||
&execution.ContainerID, &execution.ExecutorID, &execution.CreatedAt,
|
||||
&execution.StartedAt, &execution.CompletedAt,
|
||||
)
|
||||
@ -219,9 +273,14 @@ func (r *executionRepository) GetByStatus(ctx context.Context, status domain.Exe
|
||||
return nil, fmt.Errorf("failed to scan execution: %w", err)
|
||||
}
|
||||
|
||||
// Convert duration
|
||||
if durationNanos.Valid {
|
||||
execution.Duration = time.Duration(durationNanos.Int64)
|
||||
// Convert duration from PostgreSQL interval
|
||||
if durationInterval.Valid {
|
||||
duration, err := intervalToDuration(durationInterval.String)
|
||||
if err != nil {
|
||||
r.logger.Warn("Failed to parse duration interval", zap.String("interval", durationInterval.String), zap.Error(err))
|
||||
} else {
|
||||
execution.Duration = duration
|
||||
}
|
||||
}
|
||||
|
||||
executions = append(executions, execution)
|
||||
|
||||
@ -5,7 +5,6 @@ import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
@ -38,9 +37,10 @@ func (r *functionRepository) Create(ctx context.Context, function *domain.Functi
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
||||
RETURNING created_at, updated_at`
|
||||
|
||||
timeoutValue, _ := function.Timeout.Value()
|
||||
err = r.db.QueryRowContext(ctx, query,
|
||||
function.ID, function.Name, function.AppID, function.Runtime, function.Image,
|
||||
function.Handler, function.Code, envJSON, function.Timeout.Duration,
|
||||
function.Handler, function.Code, envJSON, timeoutValue,
|
||||
function.Memory, function.Owner.Type, function.Owner.Name, function.Owner.Owner,
|
||||
function.CreatedAt, function.UpdatedAt,
|
||||
).Scan(&function.CreatedAt, &function.UpdatedAt)
|
||||
@ -61,11 +61,10 @@ func (r *functionRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain
|
||||
|
||||
function := &domain.FunctionDefinition{}
|
||||
var envJSON []byte
|
||||
var timeoutNanos int64
|
||||
|
||||
err := r.db.QueryRowContext(ctx, query, id).Scan(
|
||||
&function.ID, &function.Name, &function.AppID, &function.Runtime, &function.Image,
|
||||
&function.Handler, &function.Code, &envJSON, &timeoutNanos, &function.Memory,
|
||||
&function.Handler, &function.Code, &envJSON, &function.Timeout, &function.Memory,
|
||||
&function.Owner.Type, &function.Owner.Name, &function.Owner.Owner,
|
||||
&function.CreatedAt, &function.UpdatedAt,
|
||||
)
|
||||
@ -83,9 +82,6 @@ func (r *functionRepository) GetByID(ctx context.Context, id uuid.UUID) (*domain
|
||||
return nil, fmt.Errorf("failed to unmarshal environment: %w", err)
|
||||
}
|
||||
|
||||
// Convert timeout
|
||||
function.Timeout.Duration = time.Duration(timeoutNanos)
|
||||
|
||||
return function, nil
|
||||
}
|
||||
|
||||
@ -97,11 +93,10 @@ func (r *functionRepository) GetByName(ctx context.Context, appID, name string)
|
||||
|
||||
function := &domain.FunctionDefinition{}
|
||||
var envJSON []byte
|
||||
var timeoutNanos int64
|
||||
|
||||
err := r.db.QueryRowContext(ctx, query, appID, name).Scan(
|
||||
&function.ID, &function.Name, &function.AppID, &function.Runtime, &function.Image,
|
||||
&function.Handler, &function.Code, &envJSON, &timeoutNanos, &function.Memory,
|
||||
&function.Handler, &function.Code, &envJSON, &function.Timeout, &function.Memory,
|
||||
&function.Owner.Type, &function.Owner.Name, &function.Owner.Owner,
|
||||
&function.CreatedAt, &function.UpdatedAt,
|
||||
)
|
||||
@ -119,9 +114,6 @@ func (r *functionRepository) GetByName(ctx context.Context, appID, name string)
|
||||
return nil, fmt.Errorf("failed to unmarshal environment: %w", err)
|
||||
}
|
||||
|
||||
// Convert timeout
|
||||
function.Timeout.Duration = time.Duration(timeoutNanos)
|
||||
|
||||
return function, nil
|
||||
}
|
||||
|
||||
@ -175,9 +167,10 @@ func (r *functionRepository) Update(ctx context.Context, id uuid.UUID, updates *
|
||||
WHERE id = $1
|
||||
RETURNING updated_at`
|
||||
|
||||
timeoutValue, _ := current.Timeout.Value()
|
||||
err = r.db.QueryRowContext(ctx, query,
|
||||
id, current.Name, current.Runtime, current.Image, current.Handler,
|
||||
current.Code, envJSON, int64(current.Timeout.Duration), current.Memory,
|
||||
current.Code, envJSON, timeoutValue, current.Memory,
|
||||
current.Owner.Type, current.Owner.Name, current.Owner.Owner,
|
||||
).Scan(¤t.UpdatedAt)
|
||||
|
||||
@ -241,11 +234,10 @@ func (r *functionRepository) List(ctx context.Context, appID string, limit, offs
|
||||
for rows.Next() {
|
||||
function := &domain.FunctionDefinition{}
|
||||
var envJSON []byte
|
||||
var timeoutNanos int64
|
||||
|
||||
err := rows.Scan(
|
||||
&function.ID, &function.Name, &function.AppID, &function.Runtime, &function.Image,
|
||||
&function.Handler, &function.Code, &envJSON, &timeoutNanos, &function.Memory,
|
||||
&function.Handler, &function.Code, &envJSON, &function.Timeout, &function.Memory,
|
||||
&function.Owner.Type, &function.Owner.Name, &function.Owner.Owner,
|
||||
&function.CreatedAt, &function.UpdatedAt,
|
||||
)
|
||||
@ -260,9 +252,6 @@ func (r *functionRepository) List(ctx context.Context, appID string, limit, offs
|
||||
return nil, fmt.Errorf("failed to unmarshal environment: %w", err)
|
||||
}
|
||||
|
||||
// Convert timeout
|
||||
function.Timeout.Duration = time.Duration(timeoutNanos)
|
||||
|
||||
functions = append(functions, function)
|
||||
}
|
||||
|
||||
@ -275,4 +264,4 @@ func (r *functionRepository) List(ctx context.Context, appID string, limit, offs
|
||||
|
||||
func (r *functionRepository) GetByAppID(ctx context.Context, appID string) ([]*domain.FunctionDefinition, error) {
|
||||
return r.List(ctx, appID, 1000, 0) // Get all functions for the app
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user