Faas semi worfking

This commit is contained in:
2025-08-30 23:52:37 -04:00
parent 2778cbc512
commit 67bce24899
23 changed files with 1089 additions and 135 deletions

View File

@ -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)