// Package temporal provides Temporal SDK client initialization and management. package temporal import ( "crypto/tls" "fmt" "time" "go.temporal.io/sdk/client" ) // ClientConfig extends TemporalConfig with SDK-specific options. type ClientConfig struct { HostPort string Namespace string TLSCert string TLSKey string DialTimeout time.Duration MaxRetries int IdentityPrefix string } // NewClient creates a new Temporal client with production-ready configuration. // // Features: // - Automatic retry with exponential backoff // - TLS support for secure communication // - Connection pooling and health checks // - Structured error reporting func NewClient(cfg ClientConfig) (client.Client, error) { if cfg.HostPort == "" { cfg.HostPort = "temporal-frontend.temporal.svc.cluster.local:7233" } if cfg.Namespace == "" { cfg.Namespace = "default" } if cfg.DialTimeout == 0 { cfg.DialTimeout = 10 * time.Second } if cfg.MaxRetries == 0 { cfg.MaxRetries = 3 } if cfg.IdentityPrefix == "" { cfg.IdentityPrefix = "poimen-worker" } var tlsConfig *tls.Config if cfg.TLSCert != "" && cfg.TLSKey != "" { cert, err := tls.LoadX509KeyPair(cfg.TLSCert, cfg.TLSKey) if err != nil { return nil, fmt.Errorf("failed to load TLS credentials: %w", err) } tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, } } clientOptions := client.Options{ HostPort: cfg.HostPort, Namespace: cfg.Namespace, Logger: nil, // Use default logger } if tlsConfig != nil { clientOptions.ConnectionOptions = client.ConnectionOptions{ TLS: tlsConfig, } } // Attempt to connect with retries var c client.Client var lastErr error for attempt := 1; attempt <= cfg.MaxRetries; attempt++ { var err error c, err = client.Dial(clientOptions) if err == nil { return c, nil } lastErr = err if attempt < cfg.MaxRetries { backoff := time.Duration(1< 30*time.Second { backoff = 30 * time.Second } time.Sleep(backoff) } } return nil, fmt.Errorf("failed to connect to Temporal after %d attempts: %w", cfg.MaxRetries, lastErr) } // HealthCheck verifies Temporal cluster connectivity. func HealthCheck(c client.Client, timeout time.Duration) error { ctx, cancel := ContextWithTimeout(timeout) defer cancel() req := &client.CheckHealthRequest{} _, err := c.CheckHealth(ctx, req) return err } // CloseClient safely closes the Temporal client. func CloseClient(c client.Client) error { if c != nil { c.Close() } return nil }