all repos

onasty @ 312d08fc09acfbc338373ec3b6257fc6d6fb4118

a one-time notes service
2 files changed, 83 insertions(+), 59 deletions(-)
refactor(config): make config singleton (#202)

Author: Oleksandr Smirnov olexsmir@gmail.com
Committed by: GitHub noreply@github.com
Committed at: 2025-09-01 12:55:29 +0300
Parent: 49ba283
M internal/config/config.go
···
        5
        5
         	"os"

      
        6
        6
         	"strconv"

      
        7
        7
         	"strings"

      
        
        8
        +	"sync"

      
        8
        9
         	"time"

      
        
        10
        +)

      
        
        11
        +

      
        
        12
        +var (

      
        
        13
        +	instance *Config

      
        
        14
        +	once     sync.Once

      
        9
        15
         )

      
        10
        16
         

      
        11
        17
         // Environment represents current app environment.

      ···
        71
        77
         }

      
        72
        78
         

      
        73
        79
         func NewConfig() *Config {

      
        74
        
        -	return &Config{

      
        75
        
        -		AppEnv:  Environment(getenvOrDefault("APP_ENV", "debug")),

      
        76
        
        -		AppURL:  getenvOrDefault("APP_URL", ""),

      
        77
        
        -		NatsURL: getenvOrDefault("NATS_URL", ""),

      
        
        80
        +	once.Do(func() {

      
        
        81
        +		instance = &Config{

      
        
        82
        +			AppEnv:  Environment(getenvOrDefault("APP_ENV", "debug")),

      
        
        83
        +			AppURL:  getenvOrDefault("APP_URL", ""),

      
        
        84
        +			NatsURL: getenvOrDefault("NATS_URL", ""),

      
        78
        85
         

      
        79
        
        -		CORSAllowedOrigins: strings.Split(getenvOrDefault("CORS_ALLOWED_ORIGINS", "*"), ","),

      
        80
        
        -		CORSMaxAge:         mustParseDuration(getenvOrDefault("CORS_MAX_AGE", "12h")),

      
        
        86
        +			CORSAllowedOrigins: strings.Split(getenvOrDefault("CORS_ALLOWED_ORIGINS", "*"), ","),

      
        
        87
        +			CORSMaxAge:         mustParseDuration(getenvOrDefault("CORS_MAX_AGE", "12h")),

      
        81
        88
         

      
        82
        
        -		HTTPPort:            mustGetenvOrDefaultInt("HTTP_PORT", 3000),

      
        83
        
        -		HTTPWriteTimeout:    mustParseDuration(getenvOrDefault("HTTP_WRITE_TIMEOUT", "10s")),

      
        84
        
        -		HTTPReadTimeout:     mustParseDuration(getenvOrDefault("HTTP_READ_TIMEOUT", "10s")),

      
        85
        
        -		HTTPHeaderMaxSizeMb: mustGetenvOrDefaultInt("HTTP_HEADER_MAX_SIZE_MB", 1),

      
        
        89
        +			HTTPPort:            mustGetenvOrDefaultInt("HTTP_PORT", 3000),

      
        
        90
        +			HTTPWriteTimeout:    mustParseDuration(getenvOrDefault("HTTP_WRITE_TIMEOUT", "10s")),

      
        
        91
        +			HTTPReadTimeout:     mustParseDuration(getenvOrDefault("HTTP_READ_TIMEOUT", "10s")),

      
        
        92
        +			HTTPHeaderMaxSizeMb: mustGetenvOrDefaultInt("HTTP_HEADER_MAX_SIZE_MB", 1),

      
        86
        93
         

      
        87
        
        -		PostgresDSN:      getenvOrDefault("POSTGRESQL_DSN", ""),

      
        88
        
        -		PasswordSalt:     getenvOrDefault("PASSWORD_SALT", ""),

      
        89
        
        -		NotePasswordSalt: getenvOrDefault("NOTE_PASSWORD_SALT", ""),

      
        
        94
        +			PostgresDSN:      getenvOrDefault("POSTGRESQL_DSN", ""),

      
        
        95
        +			PasswordSalt:     getenvOrDefault("PASSWORD_SALT", ""),

      
        
        96
        +			NotePasswordSalt: getenvOrDefault("NOTE_PASSWORD_SALT", ""),

      
        90
        97
         

      
        91
        
        -		RedisAddr:     getenvOrDefault("REDIS_ADDR", ""),

      
        92
        
        -		RedisPassword: getenvOrDefault("REDIS_PASSWORD", ""),

      
        93
        
        -		RedisDB:       mustGetenvOrDefaultInt(getenvOrDefault("REDIS_DB", "0"), 0),

      
        
        98
        +			RedisAddr:     getenvOrDefault("REDIS_ADDR", ""),

      
        
        99
        +			RedisPassword: getenvOrDefault("REDIS_PASSWORD", ""),

      
        
        100
        +			RedisDB:       mustGetenvOrDefaultInt(getenvOrDefault("REDIS_DB", "0"), 0),

      
        94
        101
         

      
        95
        
        -		CacheUsersTTL: mustParseDuration(getenvOrDefault("CACHE_USERS_TTL", "1h")),

      
        96
        
        -		CacheNoteTTL:  mustParseDuration(getenvOrDefault("CACHE_NOTE_TTL", "1h")),

      
        
        102
        +			CacheUsersTTL: mustParseDuration(getenvOrDefault("CACHE_USERS_TTL", "1h")),

      
        
        103
        +			CacheNoteTTL:  mustParseDuration(getenvOrDefault("CACHE_NOTE_TTL", "1h")),

      
        97
        104
         

      
        98
        
        -		JwtSigningKey: getenvOrDefault("JWT_SIGNING_KEY", ""),

      
        99
        
        -		JwtAccessTokenTTL: mustParseDuration(

      
        100
        
        -			getenvOrDefault("JWT_ACCESS_TOKEN_TTL", "15m"),

      
        101
        
        -		),

      
        102
        
        -		JwtRefreshTokenTTL: mustParseDuration(

      
        103
        
        -			getenvOrDefault("JWT_REFRESH_TOKEN_TTL", "24h"),

      
        104
        
        -		),

      
        
        105
        +			JwtSigningKey: getenvOrDefault("JWT_SIGNING_KEY", ""),

      
        
        106
        +			JwtAccessTokenTTL: mustParseDuration(

      
        
        107
        +				getenvOrDefault("JWT_ACCESS_TOKEN_TTL", "15m"),

      
        
        108
        +			),

      
        
        109
        +			JwtRefreshTokenTTL: mustParseDuration(

      
        
        110
        +				getenvOrDefault("JWT_REFRESH_TOKEN_TTL", "24h"),

      
        
        111
        +			),

      
        105
        112
         

      
        106
        
        -		GoogleClientID:    getenvOrDefault("GOOGLE_CLIENTID", ""),

      
        107
        
        -		GoogleSecret:      getenvOrDefault("GOOGLE_SECRET", ""),

      
        108
        
        -		GoogleRedirectURL: getenvOrDefault("GOOGLE_REDIRECTURL", ""),

      
        
        113
        +			GoogleClientID:    getenvOrDefault("GOOGLE_CLIENTID", ""),

      
        
        114
        +			GoogleSecret:      getenvOrDefault("GOOGLE_SECRET", ""),

      
        
        115
        +			GoogleRedirectURL: getenvOrDefault("GOOGLE_REDIRECTURL", ""),

      
        109
        116
         

      
        110
        
        -		GitHubClientID:    getenvOrDefault("GITHUB_CLIENTID", ""),

      
        111
        
        -		GitHubSecret:      getenvOrDefault("GITHUB_SECRET", ""),

      
        112
        
        -		GitHubRedirectURL: getenvOrDefault("GITHUB_REDIRECTURL", ""),

      
        
        117
        +			GitHubClientID:    getenvOrDefault("GITHUB_CLIENTID", ""),

      
        
        118
        +			GitHubSecret:      getenvOrDefault("GITHUB_SECRET", ""),

      
        
        119
        +			GitHubRedirectURL: getenvOrDefault("GITHUB_REDIRECTURL", ""),

      
        113
        120
         

      
        114
        
        -		VerificationTokenTTL:  mustParseDuration(getenvOrDefault("VERIFICATION_TOKEN_TTL", "24h")),

      
        115
        
        -		ResetPasswordTokenTTL: mustParseDuration(getenvOrDefault("RESET_PASSWORD_TOKEN_TTL", "1h")),

      
        116
        
        -		ChangeEmailTokenTTL:   mustParseDuration(getenvOrDefault("CHANGE_EMAIL_TOKEN_TTL", "24h")),

      
        
        121
        +			VerificationTokenTTL: mustParseDuration(

      
        
        122
        +				getenvOrDefault("VERIFICATION_TOKEN_TTL", "24h"),

      
        
        123
        +			),

      
        
        124
        +			ResetPasswordTokenTTL: mustParseDuration(

      
        
        125
        +				getenvOrDefault("RESET_PASSWORD_TOKEN_TTL", "1h"),

      
        
        126
        +			),

      
        
        127
        +			ChangeEmailTokenTTL: mustParseDuration(

      
        
        128
        +				getenvOrDefault("CHANGE_EMAIL_TOKEN_TTL", "24h"),

      
        
        129
        +			),

      
        117
        130
         

      
        118
        
        -		MetricsPort:    mustGetenvOrDefaultInt("METRICS_PORT", 3001),

      
        119
        
        -		MetricsEnabled: getenvOrDefault("METRICS_ENABLED", "true") == "true",

      
        
        131
        +			MetricsPort:    mustGetenvOrDefaultInt("METRICS_PORT", 3001),

      
        
        132
        +			MetricsEnabled: getenvOrDefault("METRICS_ENABLED", "true") == "true",

      
        120
        133
         

      
        121
        
        -		LogLevel:    getenvOrDefault("LOG_LEVEL", "debug"),

      
        122
        
        -		LogFormat:   getenvOrDefault("LOG_FORMAT", "json"),

      
        123
        
        -		LogShowLine: getenvOrDefault("LOG_SHOW_LINE", "true") == "true",

      
        
        134
        +			LogLevel:    getenvOrDefault("LOG_LEVEL", "debug"),

      
        
        135
        +			LogFormat:   getenvOrDefault("LOG_FORMAT", "json"),

      
        
        136
        +			LogShowLine: getenvOrDefault("LOG_SHOW_LINE", "true") == "true",

      
        124
        137
         

      
        125
        
        -		RateLimiterRPS:       mustGetenvOrDefaultInt("RATELIMITER_RPS", 100),

      
        126
        
        -		RateLimiterBurst:     mustGetenvOrDefaultInt("RATELIMITER_BURST", 10),

      
        127
        
        -		RateLimiterTTL:       mustParseDuration(getenvOrDefault("RATELIMITER_TTL", "1m")),

      
        128
        
        -		SlowRateLimiterRPS:   mustGetenvOrDefaultInt("SLOW_RATELIMITER_RPS", 2),

      
        129
        
        -		SlowRateLimiterBurst: mustGetenvOrDefaultInt("SLOW_RATELIMITER_BURST", 2),

      
        130
        
        -		SlowRateLimiterTTL:   mustParseDuration(getenvOrDefault("SLOW_RATELIMITER_TTL", "1m")),

      
        131
        
        -	}

      
        
        138
        +			RateLimiterRPS:       mustGetenvOrDefaultInt("RATELIMITER_RPS", 100),

      
        
        139
        +			RateLimiterBurst:     mustGetenvOrDefaultInt("RATELIMITER_BURST", 10),

      
        
        140
        +			RateLimiterTTL:       mustParseDuration(getenvOrDefault("RATELIMITER_TTL", "1m")),

      
        
        141
        +			SlowRateLimiterRPS:   mustGetenvOrDefaultInt("SLOW_RATELIMITER_RPS", 2),

      
        
        142
        +			SlowRateLimiterBurst: mustGetenvOrDefaultInt("SLOW_RATELIMITER_BURST", 2),

      
        
        143
        +			SlowRateLimiterTTL:   mustParseDuration(getenvOrDefault("SLOW_RATELIMITER_TTL", "1m")),

      
        
        144
        +		}

      
        
        145
        +	})

      
        
        146
        +	return instance

      
        132
        147
         }

      
        133
        148
         

      
        134
        149
         func getenvOrDefault(key, def string) string {

      
M mailer/config.go
···
        3
        3
         import (

      
        4
        4
         	"os"

      
        5
        5
         	"strconv"

      
        
        6
        +	"sync"

      
        
        7
        +)

      
        
        8
        +

      
        
        9
        +var (

      
        
        10
        +	configInstance *Config

      
        
        11
        +	once           sync.Once

      
        6
        12
         )

      
        7
        13
         

      
        8
        14
         type Config struct {

      ···
        23
        29
         }

      
        24
        30
         

      
        25
        31
         func NewConfig() *Config {

      
        26
        
        -	return &Config{

      
        27
        
        -		AppURL:         getenvOrDefault("APP_URL", ""),

      
        28
        
        -		FrontendURL:    getenvOrDefault("FRONTEND_URL", ""),

      
        29
        
        -		NatsURL:        getenvOrDefault("NATS_URL", ""),

      
        30
        
        -		MailgunFrom:    getenvOrDefault("MAILGUN_FROM", ""),

      
        31
        
        -		MailgunDomain:  getenvOrDefault("MAILGUN_DOMAIN", ""),

      
        32
        
        -		MailgunAPIKey:  getenvOrDefault("MAILGUN_API_KEY", ""),

      
        33
        
        -		LogLevel:       getenvOrDefault("LOG_LEVEL", "debug"),

      
        34
        
        -		LogFormat:      getenvOrDefault("LOG_FORMAT", "json"),

      
        35
        
        -		LogShowLine:    getenvOrDefault("LOG_SHOW_LINE", "true") == "true",

      
        36
        
        -		MetricsPort:    mustGetenvOrDefaultInt("METRICS_PORT", 8001),

      
        37
        
        -		MetricsEnabled: getenvOrDefault("METRICS_ENABLED", "true") == "true",

      
        38
        
        -	}

      
        
        32
        +	once.Do(func() {

      
        
        33
        +		configInstance = &Config{

      
        
        34
        +			AppURL:         getenvOrDefault("APP_URL", ""),

      
        
        35
        +			FrontendURL:    getenvOrDefault("FRONTEND_URL", ""),

      
        
        36
        +			NatsURL:        getenvOrDefault("NATS_URL", ""),

      
        
        37
        +			MailgunFrom:    getenvOrDefault("MAILGUN_FROM", ""),

      
        
        38
        +			MailgunDomain:  getenvOrDefault("MAILGUN_DOMAIN", ""),

      
        
        39
        +			MailgunAPIKey:  getenvOrDefault("MAILGUN_API_KEY", ""),

      
        
        40
        +			LogLevel:       getenvOrDefault("LOG_LEVEL", "debug"),

      
        
        41
        +			LogFormat:      getenvOrDefault("LOG_FORMAT", "json"),

      
        
        42
        +			LogShowLine:    getenvOrDefault("LOG_SHOW_LINE", "true") == "true",

      
        
        43
        +			MetricsPort:    mustGetenvOrDefaultInt("METRICS_PORT", 8001),

      
        
        44
        +			MetricsEnabled: getenvOrDefault("METRICS_ENABLED", "true") == "true",

      
        
        45
        +		}

      
        
        46
        +	})

      
        
        47
        +	return configInstance

      
        39
        48
         }

      
        40
        49
         

      
        41
        50
         func getenvOrDefault(key, def string) string {