Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 53 additions & 9 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@ import (
"syscall"
"time"

"github.com/akave-ai/go-akavelink/internal/errors"
"github.com/akave-ai/go-akavelink/internal/handlers"
"github.com/akave-ai/go-akavelink/internal/logging"
akavesdk "github.com/akave-ai/go-akavelink/internal/sdk"
"github.com/akave-ai/go-akavelink/internal/utils"
)

func MainFunc() {
ctx := context.Background()

// Initialize logging
logging.Info(ctx, "Starting go-akavelink server", map[string]interface{}{
"service": "go-akavelink",
"version": "1.0.0",
})

utils.LoadEnvConfig()

key := os.Getenv("AKAVE_PRIVATE_KEY")
Expand All @@ -29,17 +39,29 @@ func MainFunc() {
if blockpartsize == "" {
blockpartsize = "1048576" // 1 MiB
}

// Parse block part size to int64 as required by the SDK config
blockPartSize, parseErr := strconv.ParseInt(blockpartsize, 10, 64)
if parseErr != nil {
serviceErr := errors.NewConfigurationError("AKAVE_BLOCK_PART_SIZE", parseErr)
serviceErr = serviceErr.WithContext("value", blockpartsize)
logging.Error(ctx, "Configuration error", serviceErr)
log.Fatalf("invalid AKAVE_BLOCK_PART_SIZE %q: %v", blockpartsize, parseErr)
}

// Parse max concurrency to int as required by the SDK config
maxConcurrency, parseErr2 := strconv.Atoi(maxconcurrency)
if parseErr2 != nil {
serviceErr := errors.NewConfigurationError("AKAVE_MAX_CONCURRENCY", parseErr2)
serviceErr = serviceErr.WithContext("value", maxconcurrency)
logging.Error(ctx, "Configuration error", serviceErr)
log.Fatalf("invalid AKAVE_MAX_CONCURRENCY %q: %v", maxconcurrency, parseErr2)
}

if key == "" || node == "" {
serviceErr := errors.NewConfigurationError("Required environment variables", nil)
serviceErr = serviceErr.WithContext("missing_vars", []string{"AKAVE_PRIVATE_KEY", "AKAVE_NODE_ADDRESS"})
logging.Error(ctx, "Configuration error", serviceErr)
log.Fatal("AKAVE_PRIVATE_KEY and AKAVE_NODE_ADDRESS must be set")
}

Expand All @@ -50,16 +72,27 @@ func MainFunc() {
UseConnectionPool: true,
PrivateKeyHex: key,
}

logging.Info(ctx, "Initializing Akave SDK client", map[string]interface{}{
"node_address": node,
"max_concurrency": maxConcurrency,
"block_part_size": blockPartSize,
})

client, err := akavesdk.NewClient(cfg)
if err != nil {
serviceErr := errors.NewConfigurationError("SDK client initialization", err)
logging.Error(ctx, "Client initialization error", serviceErr)
log.Fatalf("client init error: %v", err)
}
defer func() {
if err := client.Close(); err != nil {
log.Printf("client close error: %v", err)
logging.Error(ctx, "Client close error", err)
}
}()

logging.Info(ctx, "Akave SDK client initialized successfully")

// Set up HTTP server with routes via internal/handlers
r := handlers.NewRouter(client)
// Resolve PORT from environment with default
Expand All @@ -77,28 +110,39 @@ func MainFunc() {
IdleTimeout: 60 * time.Second,
}

logging.Info(ctx, "HTTP server configured", map[string]interface{}{
"port": port,
"read_timeout": "15s",
"write_timeout": "15s",
"idle_timeout": "60s",
})

// Listen for shutdown signals
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
shutdownCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

// Start server
go func() {
log.Printf("Server listening on :%s", port)
logging.Info(ctx, "Starting HTTP server", map[string]interface{}{
"port": port,
})
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
serviceErr := errors.NewInternalError("Server startup failed", err)
logging.Error(ctx, "Server startup error", serviceErr)
log.Fatalf("server error: %v", err)
}
}()

// Block until a shutdown signal is received
<-ctx.Done()
log.Println("Shutdown signal received, shutting down gracefully...")
<-shutdownCtx.Done()
logging.Info(ctx, "Shutdown signal received, shutting down gracefully...")

shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
gracefulShutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(shutdownCtx); err != nil {
log.Printf("Server forced to shutdown: %v", err)
if err := srv.Shutdown(gracefulShutdownCtx); err != nil {
logging.Error(ctx, "Server forced to shutdown", err)
}
log.Println("Server exited cleanly")
logging.Info(ctx, "Server exited cleanly")
}

func main() {
Expand Down
Loading