diff options
| author | 2022-12-11 13:03:15 +0000 | |
|---|---|---|
| committer | 2022-12-11 13:03:15 +0000 | |
| commit | cb2b2fd8058a71826f23f60036cb0232eee113c7 (patch) | |
| tree | 761e6c0acc211c8ca9e8b957cd99d1e93668eebe /internal | |
| parent | [docs] Caching webfinger with nginx (#1242) (diff) | |
| download | gotosocial-cb2b2fd8058a71826f23f60036cb0232eee113c7.tar.xz | |
[feature] support configuring database caches (#1246)
* update config generator to support nested structs, add cache configuration options
* update envparsing test
* add cache configuration to config parse tests
* set cache configuration in testrig
* move caches to sub-cache "gts" namespace, update envparsing, add cache config docs to example config
Signed-off-by: kim <grufwub@gmail.com>
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/cache/gts.go | 63 | ||||
| -rw-r--r-- | internal/config/config.go | 52 | ||||
| -rw-r--r-- | internal/config/config_test.go (renamed from internal/config/cliparsing_test.go) | 0 | ||||
| -rw-r--r-- | internal/config/defaults.go | 59 | ||||
| -rw-r--r-- | internal/config/gen/gen.go | 249 | ||||
| -rw-r--r-- | internal/config/helpers.gen.go | 761 | ||||
| -rw-r--r-- | internal/config/state.go | 8 | ||||
| -rw-r--r-- | internal/config/testdata/test.yaml | 7 | 
8 files changed, 1109 insertions, 90 deletions
| diff --git a/internal/cache/gts.go b/internal/cache/gts.go index 9d77f5386..6083b8693 100644 --- a/internal/cache/gts.go +++ b/internal/cache/gts.go @@ -19,9 +19,8 @@  package cache  import ( -	"time" -  	"codeberg.org/gruf/go-cache/v3/result" +	"github.com/superseriousbusiness/gotosocial/internal/config"  	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"  ) @@ -100,34 +99,34 @@ func (c *gtsCaches) Init() {  func (c *gtsCaches) Start() {  	tryUntil("starting gtsmodel.Account cache", 5, func() bool { -		return c.account.Start(time.Second * 10) +		return c.account.Start(config.GetCacheGTSAccountSweepFreq())  	})  	tryUntil("starting gtsmodel.Block cache", 5, func() bool { -		return c.block.Start(time.Second * 10) +		return c.block.Start(config.GetCacheGTSBlockSweepFreq())  	})  	tryUntil("starting gtsmodel.DomainBlock cache", 5, func() bool { -		return c.domainBlock.Start(time.Second * 10) +		return c.domainBlock.Start(config.GetCacheGTSDomainBlockSweepFreq())  	})  	tryUntil("starting gtsmodel.Emoji cache", 5, func() bool { -		return c.emoji.Start(time.Second * 10) +		return c.emoji.Start(config.GetCacheGTSEmojiSweepFreq())  	})  	tryUntil("starting gtsmodel.EmojiCategory cache", 5, func() bool { -		return c.emojiCategory.Start(time.Second * 10) +		return c.emojiCategory.Start(config.GetCacheGTSEmojiCategorySweepFreq())  	})  	tryUntil("starting gtsmodel.Mention cache", 5, func() bool { -		return c.mention.Start(time.Second * 10) +		return c.mention.Start(config.GetCacheGTSMentionSweepFreq())  	})  	tryUntil("starting gtsmodel.Notification cache", 5, func() bool { -		return c.notification.Start(time.Second * 10) +		return c.notification.Start(config.GetCacheGTSNotificationSweepFreq())  	})  	tryUntil("starting gtsmodel.Status cache", 5, func() bool { -		return c.status.Start(time.Second * 10) +		return c.status.Start(config.GetCacheGTSStatusSweepFreq())  	})  	tryUntil("starting gtsmodel.Tombstone cache", 5, func() bool { -		return c.tombstone.Start(time.Second * 10) +		return c.tombstone.Start(config.GetCacheGTSTombstoneSweepFreq())  	})  	tryUntil("starting gtsmodel.User cache", 5, func() bool { -		return c.user.Start(time.Second * 10) +		return c.user.Start(config.GetCacheGTSUserSweepFreq())  	})  } @@ -195,8 +194,8 @@ func (c *gtsCaches) initAccount() {  		a2 := new(gtsmodel.Account)  		*a2 = *a1  		return a2 -	}, 1000) -	c.account.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSAccountMaxSize()) +	c.account.SetTTL(config.GetCacheGTSAccountTTL(), true)  }  func (c *gtsCaches) initBlock() { @@ -208,8 +207,8 @@ func (c *gtsCaches) initBlock() {  		b2 := new(gtsmodel.Block)  		*b2 = *b1  		return b2 -	}, 1000) -	c.block.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSBlockMaxSize()) +	c.block.SetTTL(config.GetCacheGTSBlockTTL(), true)  }  func (c *gtsCaches) initDomainBlock() { @@ -219,8 +218,8 @@ func (c *gtsCaches) initDomainBlock() {  		d2 := new(gtsmodel.DomainBlock)  		*d2 = *d1  		return d2 -	}, 1000) -	c.domainBlock.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSDomainBlockMaxSize()) +	c.domainBlock.SetTTL(config.GetCacheGTSDomainBlockTTL(), true)  }  func (c *gtsCaches) initEmoji() { @@ -233,8 +232,8 @@ func (c *gtsCaches) initEmoji() {  		e2 := new(gtsmodel.Emoji)  		*e2 = *e1  		return e2 -	}, 1000) -	c.emoji.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSEmojiMaxSize()) +	c.emoji.SetTTL(config.GetCacheGTSEmojiTTL(), true)  }  func (c *gtsCaches) initEmojiCategory() { @@ -245,8 +244,8 @@ func (c *gtsCaches) initEmojiCategory() {  		c2 := new(gtsmodel.EmojiCategory)  		*c2 = *c1  		return c2 -	}, 1000) -	c.emojiCategory.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSEmojiCategoryMaxSize()) +	c.emojiCategory.SetTTL(config.GetCacheGTSEmojiCategoryTTL(), true)  }  func (c *gtsCaches) initMention() { @@ -256,8 +255,8 @@ func (c *gtsCaches) initMention() {  		m2 := new(gtsmodel.Mention)  		*m2 = *m1  		return m2 -	}, 1000) -	c.mention.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSMentionMaxSize()) +	c.mention.SetTTL(config.GetCacheGTSMentionTTL(), true)  }  func (c *gtsCaches) initNotification() { @@ -267,8 +266,8 @@ func (c *gtsCaches) initNotification() {  		n2 := new(gtsmodel.Notification)  		*n2 = *n1  		return n2 -	}, 1000) -	c.notification.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSNotificationMaxSize()) +	c.notification.SetTTL(config.GetCacheGTSNotificationTTL(), true)  }  func (c *gtsCaches) initStatus() { @@ -280,8 +279,8 @@ func (c *gtsCaches) initStatus() {  		s2 := new(gtsmodel.Status)  		*s2 = *s1  		return s2 -	}, 1000) -	c.status.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSStatusMaxSize()) +	c.status.SetTTL(config.GetCacheGTSStatusTTL(), true)  }  // initTombstone will initialize the gtsmodel.Tombstone cache. @@ -293,8 +292,8 @@ func (c *gtsCaches) initTombstone() {  		t2 := new(gtsmodel.Tombstone)  		*t2 = *t1  		return t2 -	}, 100) -	c.tombstone.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSTombstoneMaxSize()) +	c.tombstone.SetTTL(config.GetCacheGTSTombstoneTTL(), true)  }  func (c *gtsCaches) initUser() { @@ -308,6 +307,6 @@ func (c *gtsCaches) initUser() {  		u2 := new(gtsmodel.User)  		*u2 = *u1  		return u2 -	}, 1000) -	c.user.SetTTL(time.Minute*5, false) +	}, config.GetCacheGTSUserMaxSize()) +	c.user.SetTTL(config.GetCacheGTSUserTTL(), true)  } diff --git a/internal/config/config.go b/internal/config/config.go index 047765a75..8a2c041e1 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -20,6 +20,7 @@ package config  import (  	"reflect" +	"time"  	"codeberg.org/gruf/go-bytesize"  	"github.com/mitchellh/mapstructure" @@ -129,6 +130,9 @@ type Configuration struct {  	AdvancedCookiesSamesite   string `name:"advanced-cookies-samesite" usage:"'strict' or 'lax', see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite"`  	AdvancedRateLimitRequests int    `name:"advanced-rate-limit-requests" usage:"Amount of HTTP requests to permit within a 5 minute window. 0 or less turns rate limiting off."` +	// Cache configuration vars. +	Cache CacheConfiguration `name:"cache"` +  	// TODO: move these elsewhere, these are more ephemeral vs long-running flags like above  	AdminAccountUsername  string `name:"username" usage:"the username to create/delete/etc"`  	AdminAccountEmail     string `name:"email" usage:"the email address of this account"` @@ -137,7 +141,53 @@ type Configuration struct {  	AdminMediaPruneDryRun bool   `name:"dry-run" usage:"perform a dry run and only log number of items eligible for pruning"`  } -// MarshalMap will marshal current Configuration into a map structure (useful for JSON). +type CacheConfiguration struct { +	GTS GTSCacheConfiguration `name:"gts"` +} + +type GTSCacheConfiguration struct { +	AccountMaxSize   int           `name:"account-max-size"` +	AccountTTL       time.Duration `name:"account-ttl"` +	AccountSweepFreq time.Duration `name:"account-sweep-freq"` + +	BlockMaxSize   int           `name:"block-max-size"` +	BlockTTL       time.Duration `name:"block-ttl"` +	BlockSweepFreq time.Duration `name:"block-sweep-freq"` + +	DomainBlockMaxSize   int           `name:"domain-block-max-size"` +	DomainBlockTTL       time.Duration `name:"domain-block-ttl"` +	DomainBlockSweepFreq time.Duration `name:"domain-block-sweep-freq"` + +	EmojiMaxSize   int           `name:"emoji-max-size"` +	EmojiTTL       time.Duration `name:"emoji-ttl"` +	EmojiSweepFreq time.Duration `name:"emoji-sweep-freq"` + +	EmojiCategoryMaxSize   int           `name:"emoji-category-max-size"` +	EmojiCategoryTTL       time.Duration `name:"emoji-category-ttl"` +	EmojiCategorySweepFreq time.Duration `name:"emoji-category-sweep-freq"` + +	MentionMaxSize   int           `name:"mention-max-size"` +	MentionTTL       time.Duration `name:"mention-ttl"` +	MentionSweepFreq time.Duration `name:"mention-sweep-freq"` + +	NotificationMaxSize   int           `name:"notification-max-size"` +	NotificationTTL       time.Duration `name:"notification-ttl"` +	NotificationSweepFreq time.Duration `name:"notification-sweep-freq"` + +	StatusMaxSize   int           `name:"status-max-size"` +	StatusTTL       time.Duration `name:"status-ttl"` +	StatusSweepFreq time.Duration `name:"status-sweep-freq"` + +	TombstoneMaxSize   int           `name:"tombstone-max-size"` +	TombstoneTTL       time.Duration `name:"tombstone-ttl"` +	TombstoneSweepFreq time.Duration `name:"tombstone-sweep-freq"` + +	UserMaxSize   int           `name:"user-max-size"` +	UserTTL       time.Duration `name:"user-ttl"` +	UserSweepFreq time.Duration `name:"user-sweep-freq"` +} + +// MarshalMap will marshal current Configuration into a map structure (useful for JSON/TOML/YAML).  func (cfg *Configuration) MarshalMap() (map[string]interface{}, error) {  	var dst map[string]interface{}  	dec, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ diff --git a/internal/config/cliparsing_test.go b/internal/config/config_test.go index 5f41cbe08..5f41cbe08 100644 --- a/internal/config/cliparsing_test.go +++ b/internal/config/config_test.go diff --git a/internal/config/defaults.go b/internal/config/defaults.go index be537a0df..4fd783611 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -18,7 +18,12 @@  package config -import "github.com/coreos/go-oidc/v3/oidc" +import ( +	"time" + +	"codeberg.org/gruf/go-bytesize" +	"github.com/coreos/go-oidc/v3/oidc" +)  // Defaults contains a populated Configuration with reasonable defaults. Note that  // if you use this, you will still need to set Host, and, if desired, ConfigPath. @@ -56,13 +61,13 @@ var Defaults = Configuration{  	AccountsReasonRequired:   true,  	AccountsAllowCustomCSS:   false, -	MediaImageMaxSize:        10485760, // 10mb -	MediaVideoMaxSize:        41943040, // 40mb +	MediaImageMaxSize:        10 * bytesize.MiB, +	MediaVideoMaxSize:        40 * bytesize.MiB,  	MediaDescriptionMinChars: 0,  	MediaDescriptionMaxChars: 500,  	MediaRemoteCacheDays:     30, -	MediaEmojiLocalMaxSize:   51200,  // 50kb -	MediaEmojiRemoteMaxSize:  102400, // 100kb +	MediaEmojiLocalMaxSize:   50 * bytesize.KiB, +	MediaEmojiRemoteMaxSize:  100 * bytesize.KiB,  	StorageBackend:       "local",  	StorageLocalBasePath: "/gotosocial/storage", @@ -101,4 +106,48 @@ var Defaults = Configuration{  	AdvancedCookiesSamesite:   "lax",  	AdvancedRateLimitRequests: 1000, // per 5 minutes + +	Cache: CacheConfiguration{ +		GTS: GTSCacheConfiguration{ +			AccountMaxSize:   100, +			AccountTTL:       time.Minute * 5, +			AccountSweepFreq: time.Second * 10, + +			BlockMaxSize:   100, +			BlockTTL:       time.Minute * 5, +			BlockSweepFreq: time.Second * 10, + +			DomainBlockMaxSize:   1000, +			DomainBlockTTL:       time.Hour * 24, +			DomainBlockSweepFreq: time.Minute, + +			EmojiMaxSize:   500, +			EmojiTTL:       time.Minute * 5, +			EmojiSweepFreq: time.Second * 10, + +			EmojiCategoryMaxSize:   100, +			EmojiCategoryTTL:       time.Minute * 5, +			EmojiCategorySweepFreq: time.Second * 10, + +			MentionMaxSize:   500, +			MentionTTL:       time.Minute * 5, +			MentionSweepFreq: time.Second * 10, + +			NotificationMaxSize:   500, +			NotificationTTL:       time.Minute * 5, +			NotificationSweepFreq: time.Second * 10, + +			StatusMaxSize:   500, +			StatusTTL:       time.Minute * 5, +			StatusSweepFreq: time.Second * 10, + +			TombstoneMaxSize:   100, +			TombstoneTTL:       time.Minute * 5, +			TombstoneSweepFreq: time.Second * 10, + +			UserMaxSize:   100, +			UserTTL:       time.Minute * 5, +			UserSweepFreq: time.Second * 10, +		}, +	},  } diff --git a/internal/config/gen/gen.go b/internal/config/gen/gen.go index a0db7e0e0..9065528e6 100644 --- a/internal/config/gen/gen.go +++ b/internal/config/gen/gen.go @@ -21,11 +21,14 @@ package main  import (  	"flag"  	"fmt" +	"io"  	"os"  	"os/exec"  	"reflect" +	"strings" +	"time" -	"github.com/superseriousbusiness/gotosocial/internal/config" +	"codeberg.org/gruf/go-bytesize"  )  const license = `/* @@ -47,15 +50,154 @@ const license = `/*  */  ` +type Configuration struct { +	LogLevel        string   `name:"log-level" usage:"Log level to run at: [trace, debug, info, warn, fatal]"` +	LogDbQueries    bool     `name:"log-db-queries" usage:"Log database queries verbosely when log-level is trace or debug"` +	ApplicationName string   `name:"application-name" usage:"Name of the application, used in various places internally"` +	LandingPageUser string   `name:"landing-page-user" usage:"the user that should be shown on the instance's landing page"` +	ConfigPath      string   `name:"config-path" usage:"Path to a file containing gotosocial configuration. Values set in this file will be overwritten by values set as env vars or arguments"` +	Host            string   `name:"host" usage:"Hostname to use for the server (eg., example.org, gotosocial.whatever.com). DO NOT change this on a server that's already run!"` +	AccountDomain   string   `name:"account-domain" usage:"Domain to use in account names (eg., example.org, whatever.com). If not set, will default to the setting for host. DO NOT change this on a server that's already run!"` +	Protocol        string   `name:"protocol" usage:"Protocol to use for the REST api of the server (only use http if you are debugging or behind a reverse proxy!)"` +	BindAddress     string   `name:"bind-address" usage:"Bind address to use for the GoToSocial server (eg., 0.0.0.0, 172.138.0.9, [::], localhost). For ipv6, enclose the address in square brackets, eg [2001:db8::fed1]. Default binds to all interfaces."` +	Port            int      `name:"port" usage:"Port to use for GoToSocial. Change this to 443 if you're running the binary directly on the host machine."` +	TrustedProxies  []string `name:"trusted-proxies" usage:"Proxies to trust when parsing x-forwarded headers into real IPs."` +	SoftwareVersion string   `name:"software-version" usage:""` + +	DbType      string `name:"db-type" usage:"Database type: eg., postgres"` +	DbAddress   string `name:"db-address" usage:"Database ipv4 address, hostname, or filename"` +	DbPort      int    `name:"db-port" usage:"Database port"` +	DbUser      string `name:"db-user" usage:"Database username"` +	DbPassword  string `name:"db-password" usage:"Database password"` +	DbDatabase  string `name:"db-database" usage:"Database name"` +	DbTLSMode   string `name:"db-tls-mode" usage:"Database tls mode"` +	DbTLSCACert string `name:"db-tls-ca-cert" usage:"Path to CA cert for db tls connection"` + +	WebTemplateBaseDir string `name:"web-template-base-dir" usage:"Basedir for html templating files for rendering pages and composing emails."` +	WebAssetBaseDir    string `name:"web-asset-base-dir" usage:"Directory to serve static assets from, accessible at example.org/assets/"` + +	InstanceExposePeers            bool `name:"instance-expose-peers" usage:"Allow unauthenticated users to query /api/v1/instance/peers?filter=open"` +	InstanceExposeSuspended        bool `name:"instance-expose-suspended" usage:"Expose suspended instances via web UI, and allow unauthenticated users to query /api/v1/instance/peers?filter=suspended"` +	InstanceExposePublicTimeline   bool `name:"instance-expose-public-timeline" usage:"Allow unauthenticated users to query /api/v1/timelines/public"` +	InstanceDeliverToSharedInboxes bool `name:"instance-deliver-to-shared-inboxes" usage:"Deliver federated messages to shared inboxes, if they're available."` + +	AccountsRegistrationOpen bool `name:"accounts-registration-open" usage:"Allow anyone to submit an account signup request. If false, server will be invite-only."` +	AccountsApprovalRequired bool `name:"accounts-approval-required" usage:"Do account signups require approval by an admin or moderator before user can log in? If false, new registrations will be automatically approved."` +	AccountsReasonRequired   bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"` +	AccountsAllowCustomCSS   bool `name:"accounts-allow-custom-css" usage:"Allow accounts to enable custom CSS for their profile pages and statuses."` + +	MediaImageMaxSize        bytesize.Size `name:"media-image-max-size" usage:"Max size of accepted images in bytes"` +	MediaVideoMaxSize        bytesize.Size `name:"media-video-max-size" usage:"Max size of accepted videos in bytes"` +	MediaDescriptionMinChars int           `name:"media-description-min-chars" usage:"Min required chars for an image description"` +	MediaDescriptionMaxChars int           `name:"media-description-max-chars" usage:"Max permitted chars for an image description"` +	MediaRemoteCacheDays     int           `name:"media-remote-cache-days" usage:"Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely."` +	MediaEmojiLocalMaxSize   bytesize.Size `name:"media-emoji-local-max-size" usage:"Max size in bytes of emojis uploaded to this instance via the admin API."` +	MediaEmojiRemoteMaxSize  bytesize.Size `name:"media-emoji-remote-max-size" usage:"Max size in bytes of emojis to download from other instances."` + +	StorageBackend       string `name:"storage-backend" usage:"Storage backend to use for media attachments"` +	StorageLocalBasePath string `name:"storage-local-base-path" usage:"Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir."` +	StorageS3Endpoint    string `name:"storage-s3-endpoint" usage:"S3 Endpoint URL (e.g 'minio.example.org:9000')"` +	StorageS3AccessKey   string `name:"storage-s3-access-key" usage:"S3 Access Key"` +	StorageS3SecretKey   string `name:"storage-s3-secret-key" usage:"S3 Secret Key"` +	StorageS3UseSSL      bool   `name:"storage-s3-use-ssl" usage:"Use SSL for S3 connections. Only set this to 'false' when testing locally"` +	StorageS3BucketName  string `name:"storage-s3-bucket" usage:"Place blobs in this bucket"` +	StorageS3Proxy       bool   `name:"storage-s3-proxy" usage:"Proxy S3 contents through GoToSocial instead of redirecting to a presigned URL"` + +	StatusesMaxChars           int `name:"statuses-max-chars" usage:"Max permitted characters for posted statuses"` +	StatusesCWMaxChars         int `name:"statuses-cw-max-chars" usage:"Max permitted characters for content/spoiler warnings on statuses"` +	StatusesPollMaxOptions     int `name:"statuses-poll-max-options" usage:"Max amount of options permitted on a poll"` +	StatusesPollOptionMaxChars int `name:"statuses-poll-option-max-chars" usage:"Max amount of characters for a poll option"` +	StatusesMediaMaxFiles      int `name:"statuses-media-max-files" usage:"Maximum number of media files/attachments per status"` + +	LetsEncryptEnabled      bool   `name:"letsencrypt-enabled" usage:"Enable letsencrypt TLS certs for this server. If set to true, then cert dir also needs to be set (or take the default)."` +	LetsEncryptPort         int    `name:"letsencrypt-port" usage:"Port to listen on for letsencrypt certificate challenges. Must not be the same as the GtS webserver/API port."` +	LetsEncryptCertDir      string `name:"letsencrypt-cert-dir" usage:"Directory to store acquired letsencrypt certificates."` +	LetsEncryptEmailAddress string `name:"letsencrypt-email-address" usage:"Email address to use when requesting letsencrypt certs. Will receive updates on cert expiry etc."` + +	OIDCEnabled          bool     `name:"oidc-enabled" usage:"Enabled OIDC authorization for this instance. If set to true, then the other OIDC flags must also be set."` +	OIDCIdpName          string   `name:"oidc-idp-name" usage:"Name of the OIDC identity provider. Will be shown to the user when logging in."` +	OIDCSkipVerification bool     `name:"oidc-skip-verification" usage:"Skip verification of tokens returned by the OIDC provider. Should only be set to 'true' for testing purposes, never in a production environment!"` +	OIDCIssuer           string   `name:"oidc-issuer" usage:"Address of the OIDC issuer. Should be the web address, including protocol, at which the issuer can be reached. Eg., 'https://example.org/auth'"` +	OIDCClientID         string   `name:"oidc-client-id" usage:"ClientID of GoToSocial, as registered with the OIDC provider."` +	OIDCClientSecret     string   `name:"oidc-client-secret" usage:"ClientSecret of GoToSocial, as registered with the OIDC provider."` +	OIDCScopes           []string `name:"oidc-scopes" usage:"OIDC scopes."` +	OIDCLinkExisting     bool     `name:"oidc-link-existing" usage:"link existing user accounts to OIDC logins based on the stored email value"` + +	SMTPHost     string `name:"smtp-host" usage:"Host of the smtp server. Eg., 'smtp.eu.mailgun.org'"` +	SMTPPort     int    `name:"smtp-port" usage:"Port of the smtp server. Eg., 587"` +	SMTPUsername string `name:"smtp-username" usage:"Username to authenticate with the smtp server as. Eg., 'postmaster@mail.example.org'"` +	SMTPPassword string `name:"smtp-password" usage:"Password to pass to the smtp server."` +	SMTPFrom     string `name:"smtp-from" usage:"Address to use as the 'from' field of the email. Eg., 'gotosocial@example.org'"` + +	SyslogEnabled  bool   `name:"syslog-enabled" usage:"Enable the syslog logging hook. Logs will be mirrored to the configured destination."` +	SyslogProtocol string `name:"syslog-protocol" usage:"Protocol to use when directing logs to syslog. Leave empty to connect to local syslog."` +	SyslogAddress  string `name:"syslog-address" usage:"Address:port to send syslog logs to. Leave empty to connect to local syslog."` + +	AdvancedCookiesSamesite   string `name:"advanced-cookies-samesite" usage:"'strict' or 'lax', see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite"` +	AdvancedRateLimitRequests int    `name:"advanced-rate-limit-requests" usage:"Amount of HTTP requests to permit within a 5 minute window. 0 or less turns rate limiting off."` + +	// Cache configuration vars. +	Cache CacheConfiguration `name:"cache"` + +	// TODO: move these elsewhere, these are more ephemeral vs long-running flags like above +	AdminAccountUsername  string `name:"username" usage:"the username to create/delete/etc"` +	AdminAccountEmail     string `name:"email" usage:"the email address of this account"` +	AdminAccountPassword  string `name:"password" usage:"the password to set for this account"` +	AdminTransPath        string `name:"path" usage:"the path of the file to import from/export to"` +	AdminMediaPruneDryRun bool   `name:"dry-run" usage:"perform a dry run and only log number of items eligible for pruning"` +} + +type CacheConfiguration struct { +	GTS GTSCacheConfiguration `name:"gts"` +} + +type GTSCacheConfiguration struct { +	AccountMaxSize   int           `name:"account-max-size"` +	AccountTTL       time.Duration `name:"account-ttl"` +	AccountSweepFreq time.Duration `name:"account-sweep-freq"` + +	BlockMaxSize   int           `name:"block-max-size"` +	BlockTTL       time.Duration `name:"block-ttl"` +	BlockSweepFreq time.Duration `name:"block-sweep-freq"` + +	DomainBlockMaxSize   int           `name:"domain-block-max-size"` +	DomainBlockTTL       time.Duration `name:"domain-block-ttl"` +	DomainBlockSweepFreq time.Duration `name:"domain-block-sweep-freq"` + +	EmojiMaxSize   int           `name:"emoji-max-size"` +	EmojiTTL       time.Duration `name:"emoji-ttl"` +	EmojiSweepFreq time.Duration `name:"emoji-sweep-freq"` + +	EmojiCategoryMaxSize   int           `name:"emoji-category-max-size"` +	EmojiCategoryTTL       time.Duration `name:"emoji-category-ttl"` +	EmojiCategorySweepFreq time.Duration `name:"emoji-category-sweep-freq"` + +	MentionMaxSize   int           `name:"mention-max-size"` +	MentionTTL       time.Duration `name:"mention-ttl"` +	MentionSweepFreq time.Duration `name:"mention-sweep-freq"` + +	NotificationMaxSize   int           `name:"notification-max-size"` +	NotificationTTL       time.Duration `name:"notification-ttl"` +	NotificationSweepFreq time.Duration `name:"notification-sweep-freq"` + +	StatusMaxSize   int           `name:"status-max-size"` +	StatusTTL       time.Duration `name:"status-ttl"` +	StatusSweepFreq time.Duration `name:"status-sweep-freq"` + +	TombstoneMaxSize   int           `name:"tombstone-max-size"` +	TombstoneTTL       time.Duration `name:"tombstone-ttl"` +	TombstoneSweepFreq time.Duration `name:"tombstone-sweep-freq"` + +	UserMaxSize   int           `name:"user-max-size"` +	UserTTL       time.Duration `name:"user-ttl"` +	UserSweepFreq time.Duration `name:"user-sweep-freq"` +} +  func main() { -	var ( -		out string -		gen string -	) +	var out string  	// Load runtime config flags  	flag.StringVar(&out, "out", "", "Generated file output path") -	flag.StringVar(&gen, "gen", "helpers", "Type of file to generate (helpers)")  	flag.Parse()  	// Open output file path @@ -64,50 +206,61 @@ func main() {  		panic(err)  	} -	switch gen { -	// Generate config field helper methods -	case "helpers": -		fmt.Fprint(output, "// THIS IS A GENERATED FILE, DO NOT EDIT BY HAND\n") -		fmt.Fprint(output, license) -		fmt.Fprint(output, "package config\n\n") -		fmt.Fprint(output, "import \"codeberg.org/gruf/go-bytesize\"\n\n") -		t := reflect.TypeOf(config.Configuration{}) -		for i := 0; i < t.NumField(); i++ { -			field := t.Field(i) - -			// ConfigState structure helper methods -			fmt.Fprintf(output, "// Get%s safely fetches the Configuration value for state's '%s' field\n", field.Name, field.Name) -			fmt.Fprintf(output, "func (st *ConfigState) Get%s() (v %s) {\n", field.Name, field.Type.String()) -			fmt.Fprintf(output, "\tst.mutex.Lock()\n") -			fmt.Fprintf(output, "\tv = st.config.%s\n", field.Name) -			fmt.Fprintf(output, "\tst.mutex.Unlock()\n") -			fmt.Fprintf(output, "\treturn\n") -			fmt.Fprintf(output, "}\n\n") -			fmt.Fprintf(output, "// Set%s safely sets the Configuration value for state's '%s' field\n", field.Name, field.Name) -			fmt.Fprintf(output, "func (st *ConfigState) Set%s(v %s) {\n", field.Name, field.Type.String()) -			fmt.Fprintf(output, "\tst.mutex.Lock()\n") -			fmt.Fprintf(output, "\tdefer st.mutex.Unlock()\n") -			fmt.Fprintf(output, "\tst.config.%s = v\n", field.Name) -			fmt.Fprintf(output, "\tst.reloadToViper()\n") -			fmt.Fprintf(output, "}\n\n") - -			// Global ConfigState helper methods -			// TODO: remove when we pass around a ConfigState{} -			fmt.Fprintf(output, "// %sFlag returns the flag name for the '%s' field\n", field.Name, field.Name) -			fmt.Fprintf(output, "func %sFlag() string { return \"%s\" }\n\n", field.Name, field.Tag.Get("name")) -			fmt.Fprintf(output, "// Get%s safely fetches the value for global configuration '%s' field\n", field.Name, field.Name) -			fmt.Fprintf(output, "func Get%[1]s() %[2]s { return global.Get%[1]s() }\n\n", field.Name, field.Type.String()) -			fmt.Fprintf(output, "// Set%s safely sets the value for global configuration '%s' field\n", field.Name, field.Name) -			fmt.Fprintf(output, "func Set%[1]s(v %[2]s) { global.Set%[1]s(v) }\n\n", field.Name, field.Type.String()) -		} -		_ = output.Close() -		_ = exec.Command("gofumports", "-w", out).Run() +	fmt.Fprint(output, "// THIS IS A GENERATED FILE, DO NOT EDIT BY HAND\n") +	fmt.Fprint(output, license) +	fmt.Fprint(output, "package config\n\n") +	fmt.Fprint(output, "import \"codeberg.org/gruf/go-bytesize\"\n\n") +	generateFields(output, nil, reflect.TypeOf(Configuration{})) +	_ = output.Close() +	_ = exec.Command("gofumports", "-w", out).Run() -	// The plain here is that eventually we might be able +	// The plan here is that eventually we might be able  	// to generate an example configuration from struct tags +} + +func generateFields(output io.Writer, prefixes []string, t reflect.Type) { +	for i := 0; i < t.NumField(); i++ { +		field := t.Field(i) + +		if ft := field.Type; ft.Kind() == reflect.Struct { +			// This is a struct field containing further nested config vars. +			generateFields(output, append(prefixes, field.Name), ft) +			continue +		} + +		// Get prefixed config variable name +		name := strings.Join(prefixes, "") + field.Name + +		// Get period-separated (if nested) config variable "path" +		fieldPath := strings.Join(append(prefixes, field.Name), ".") + +		// Get dash-separated config variable CLI flag "path" +		flagPath := strings.Join(append(prefixes, field.Tag.Get("name")), "-") +		flagPath = strings.ToLower(flagPath) + +		// ConfigState structure helper methods +		fmt.Fprintf(output, "// Get%s safely fetches the Configuration value for state's '%s' field\n", name, fieldPath) +		fmt.Fprintf(output, "func (st *ConfigState) Get%s() (v %s) {\n", name, field.Type.String()) +		fmt.Fprintf(output, "\tst.mutex.Lock()\n") +		fmt.Fprintf(output, "\tv = st.config.%s\n", fieldPath) +		fmt.Fprintf(output, "\tst.mutex.Unlock()\n") +		fmt.Fprintf(output, "\treturn\n") +		fmt.Fprintf(output, "}\n\n") +		fmt.Fprintf(output, "// Set%s safely sets the Configuration value for state's '%s' field\n", name, fieldPath) +		fmt.Fprintf(output, "func (st *ConfigState) Set%s(v %s) {\n", name, field.Type.String()) +		fmt.Fprintf(output, "\tst.mutex.Lock()\n") +		fmt.Fprintf(output, "\tdefer st.mutex.Unlock()\n") +		fmt.Fprintf(output, "\tst.config.%s = v\n", fieldPath) +		fmt.Fprintf(output, "\tst.reloadToViper()\n") +		fmt.Fprintf(output, "}\n\n") -	// Unknown type -	default: -		panic("unknown generation type: " + gen) +		// Global ConfigState helper methods +		// TODO: remove when we pass around a ConfigState{} +		fmt.Fprintf(output, "// %sFlag returns the flag name for the '%s' field\n", name, fieldPath) +		fmt.Fprintf(output, "func %sFlag() string { return \"%s\" }\n\n", name, flagPath) +		fmt.Fprintf(output, "// Get%s safely fetches the value for global configuration '%s' field\n", name, fieldPath) +		fmt.Fprintf(output, "func Get%[1]s() %[2]s { return global.Get%[1]s() }\n\n", name, field.Type.String()) +		fmt.Fprintf(output, "// Set%s safely sets the value for global configuration '%s' field\n", name, fieldPath) +		fmt.Fprintf(output, "func Set%[1]s(v %[2]s) { global.Set%[1]s(v) }\n\n", name, field.Type.String())  	}  } diff --git a/internal/config/helpers.gen.go b/internal/config/helpers.gen.go index 4b834998a..62894b4d5 100644 --- a/internal/config/helpers.gen.go +++ b/internal/config/helpers.gen.go @@ -18,7 +18,11 @@  */  package config -import "codeberg.org/gruf/go-bytesize" +import ( +	"time" + +	"codeberg.org/gruf/go-bytesize" +)  // GetLogLevel safely fetches the Configuration value for state's 'LogLevel' field  func (st *ConfigState) GetLogLevel() (v string) { @@ -1820,6 +1824,760 @@ func GetAdvancedRateLimitRequests() int { return global.GetAdvancedRateLimitRequ  // SetAdvancedRateLimitRequests safely sets the value for global configuration 'AdvancedRateLimitRequests' field  func SetAdvancedRateLimitRequests(v int) { global.SetAdvancedRateLimitRequests(v) } +// GetCacheGTSAccountMaxSize safely fetches the Configuration value for state's 'Cache.GTS.AccountMaxSize' field +func (st *ConfigState) GetCacheGTSAccountMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.AccountMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSAccountMaxSize safely sets the Configuration value for state's 'Cache.GTS.AccountMaxSize' field +func (st *ConfigState) SetCacheGTSAccountMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.AccountMaxSize = v +	st.reloadToViper() +} + +// CacheGTSAccountMaxSizeFlag returns the flag name for the 'Cache.GTS.AccountMaxSize' field +func CacheGTSAccountMaxSizeFlag() string { return "cache-gts-account-max-size" } + +// GetCacheGTSAccountMaxSize safely fetches the value for global configuration 'Cache.GTS.AccountMaxSize' field +func GetCacheGTSAccountMaxSize() int { return global.GetCacheGTSAccountMaxSize() } + +// SetCacheGTSAccountMaxSize safely sets the value for global configuration 'Cache.GTS.AccountMaxSize' field +func SetCacheGTSAccountMaxSize(v int) { global.SetCacheGTSAccountMaxSize(v) } + +// GetCacheGTSAccountTTL safely fetches the Configuration value for state's 'Cache.GTS.AccountTTL' field +func (st *ConfigState) GetCacheGTSAccountTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.AccountTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSAccountTTL safely sets the Configuration value for state's 'Cache.GTS.AccountTTL' field +func (st *ConfigState) SetCacheGTSAccountTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.AccountTTL = v +	st.reloadToViper() +} + +// CacheGTSAccountTTLFlag returns the flag name for the 'Cache.GTS.AccountTTL' field +func CacheGTSAccountTTLFlag() string { return "cache-gts-account-ttl" } + +// GetCacheGTSAccountTTL safely fetches the value for global configuration 'Cache.GTS.AccountTTL' field +func GetCacheGTSAccountTTL() time.Duration { return global.GetCacheGTSAccountTTL() } + +// SetCacheGTSAccountTTL safely sets the value for global configuration 'Cache.GTS.AccountTTL' field +func SetCacheGTSAccountTTL(v time.Duration) { global.SetCacheGTSAccountTTL(v) } + +// GetCacheGTSAccountSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.AccountSweepFreq' field +func (st *ConfigState) GetCacheGTSAccountSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.AccountSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSAccountSweepFreq safely sets the Configuration value for state's 'Cache.GTS.AccountSweepFreq' field +func (st *ConfigState) SetCacheGTSAccountSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.AccountSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSAccountSweepFreqFlag returns the flag name for the 'Cache.GTS.AccountSweepFreq' field +func CacheGTSAccountSweepFreqFlag() string { return "cache-gts-account-sweep-freq" } + +// GetCacheGTSAccountSweepFreq safely fetches the value for global configuration 'Cache.GTS.AccountSweepFreq' field +func GetCacheGTSAccountSweepFreq() time.Duration { return global.GetCacheGTSAccountSweepFreq() } + +// SetCacheGTSAccountSweepFreq safely sets the value for global configuration 'Cache.GTS.AccountSweepFreq' field +func SetCacheGTSAccountSweepFreq(v time.Duration) { global.SetCacheGTSAccountSweepFreq(v) } + +// GetCacheGTSBlockMaxSize safely fetches the Configuration value for state's 'Cache.GTS.BlockMaxSize' field +func (st *ConfigState) GetCacheGTSBlockMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.BlockMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSBlockMaxSize safely sets the Configuration value for state's 'Cache.GTS.BlockMaxSize' field +func (st *ConfigState) SetCacheGTSBlockMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.BlockMaxSize = v +	st.reloadToViper() +} + +// CacheGTSBlockMaxSizeFlag returns the flag name for the 'Cache.GTS.BlockMaxSize' field +func CacheGTSBlockMaxSizeFlag() string { return "cache-gts-block-max-size" } + +// GetCacheGTSBlockMaxSize safely fetches the value for global configuration 'Cache.GTS.BlockMaxSize' field +func GetCacheGTSBlockMaxSize() int { return global.GetCacheGTSBlockMaxSize() } + +// SetCacheGTSBlockMaxSize safely sets the value for global configuration 'Cache.GTS.BlockMaxSize' field +func SetCacheGTSBlockMaxSize(v int) { global.SetCacheGTSBlockMaxSize(v) } + +// GetCacheGTSBlockTTL safely fetches the Configuration value for state's 'Cache.GTS.BlockTTL' field +func (st *ConfigState) GetCacheGTSBlockTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.BlockTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSBlockTTL safely sets the Configuration value for state's 'Cache.GTS.BlockTTL' field +func (st *ConfigState) SetCacheGTSBlockTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.BlockTTL = v +	st.reloadToViper() +} + +// CacheGTSBlockTTLFlag returns the flag name for the 'Cache.GTS.BlockTTL' field +func CacheGTSBlockTTLFlag() string { return "cache-gts-block-ttl" } + +// GetCacheGTSBlockTTL safely fetches the value for global configuration 'Cache.GTS.BlockTTL' field +func GetCacheGTSBlockTTL() time.Duration { return global.GetCacheGTSBlockTTL() } + +// SetCacheGTSBlockTTL safely sets the value for global configuration 'Cache.GTS.BlockTTL' field +func SetCacheGTSBlockTTL(v time.Duration) { global.SetCacheGTSBlockTTL(v) } + +// GetCacheGTSBlockSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.BlockSweepFreq' field +func (st *ConfigState) GetCacheGTSBlockSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.BlockSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSBlockSweepFreq safely sets the Configuration value for state's 'Cache.GTS.BlockSweepFreq' field +func (st *ConfigState) SetCacheGTSBlockSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.BlockSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSBlockSweepFreqFlag returns the flag name for the 'Cache.GTS.BlockSweepFreq' field +func CacheGTSBlockSweepFreqFlag() string { return "cache-gts-block-sweep-freq" } + +// GetCacheGTSBlockSweepFreq safely fetches the value for global configuration 'Cache.GTS.BlockSweepFreq' field +func GetCacheGTSBlockSweepFreq() time.Duration { return global.GetCacheGTSBlockSweepFreq() } + +// SetCacheGTSBlockSweepFreq safely sets the value for global configuration 'Cache.GTS.BlockSweepFreq' field +func SetCacheGTSBlockSweepFreq(v time.Duration) { global.SetCacheGTSBlockSweepFreq(v) } + +// GetCacheGTSDomainBlockMaxSize safely fetches the Configuration value for state's 'Cache.GTS.DomainBlockMaxSize' field +func (st *ConfigState) GetCacheGTSDomainBlockMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.DomainBlockMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSDomainBlockMaxSize safely sets the Configuration value for state's 'Cache.GTS.DomainBlockMaxSize' field +func (st *ConfigState) SetCacheGTSDomainBlockMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.DomainBlockMaxSize = v +	st.reloadToViper() +} + +// CacheGTSDomainBlockMaxSizeFlag returns the flag name for the 'Cache.GTS.DomainBlockMaxSize' field +func CacheGTSDomainBlockMaxSizeFlag() string { return "cache-gts-domain-block-max-size" } + +// GetCacheGTSDomainBlockMaxSize safely fetches the value for global configuration 'Cache.GTS.DomainBlockMaxSize' field +func GetCacheGTSDomainBlockMaxSize() int { return global.GetCacheGTSDomainBlockMaxSize() } + +// SetCacheGTSDomainBlockMaxSize safely sets the value for global configuration 'Cache.GTS.DomainBlockMaxSize' field +func SetCacheGTSDomainBlockMaxSize(v int) { global.SetCacheGTSDomainBlockMaxSize(v) } + +// GetCacheGTSDomainBlockTTL safely fetches the Configuration value for state's 'Cache.GTS.DomainBlockTTL' field +func (st *ConfigState) GetCacheGTSDomainBlockTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.DomainBlockTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSDomainBlockTTL safely sets the Configuration value for state's 'Cache.GTS.DomainBlockTTL' field +func (st *ConfigState) SetCacheGTSDomainBlockTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.DomainBlockTTL = v +	st.reloadToViper() +} + +// CacheGTSDomainBlockTTLFlag returns the flag name for the 'Cache.GTS.DomainBlockTTL' field +func CacheGTSDomainBlockTTLFlag() string { return "cache-gts-domain-block-ttl" } + +// GetCacheGTSDomainBlockTTL safely fetches the value for global configuration 'Cache.GTS.DomainBlockTTL' field +func GetCacheGTSDomainBlockTTL() time.Duration { return global.GetCacheGTSDomainBlockTTL() } + +// SetCacheGTSDomainBlockTTL safely sets the value for global configuration 'Cache.GTS.DomainBlockTTL' field +func SetCacheGTSDomainBlockTTL(v time.Duration) { global.SetCacheGTSDomainBlockTTL(v) } + +// GetCacheGTSDomainBlockSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.DomainBlockSweepFreq' field +func (st *ConfigState) GetCacheGTSDomainBlockSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.DomainBlockSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSDomainBlockSweepFreq safely sets the Configuration value for state's 'Cache.GTS.DomainBlockSweepFreq' field +func (st *ConfigState) SetCacheGTSDomainBlockSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.DomainBlockSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSDomainBlockSweepFreqFlag returns the flag name for the 'Cache.GTS.DomainBlockSweepFreq' field +func CacheGTSDomainBlockSweepFreqFlag() string { return "cache-gts-domain-block-sweep-freq" } + +// GetCacheGTSDomainBlockSweepFreq safely fetches the value for global configuration 'Cache.GTS.DomainBlockSweepFreq' field +func GetCacheGTSDomainBlockSweepFreq() time.Duration { return global.GetCacheGTSDomainBlockSweepFreq() } + +// SetCacheGTSDomainBlockSweepFreq safely sets the value for global configuration 'Cache.GTS.DomainBlockSweepFreq' field +func SetCacheGTSDomainBlockSweepFreq(v time.Duration) { global.SetCacheGTSDomainBlockSweepFreq(v) } + +// GetCacheGTSEmojiMaxSize safely fetches the Configuration value for state's 'Cache.GTS.EmojiMaxSize' field +func (st *ConfigState) GetCacheGTSEmojiMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.EmojiMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSEmojiMaxSize safely sets the Configuration value for state's 'Cache.GTS.EmojiMaxSize' field +func (st *ConfigState) SetCacheGTSEmojiMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.EmojiMaxSize = v +	st.reloadToViper() +} + +// CacheGTSEmojiMaxSizeFlag returns the flag name for the 'Cache.GTS.EmojiMaxSize' field +func CacheGTSEmojiMaxSizeFlag() string { return "cache-gts-emoji-max-size" } + +// GetCacheGTSEmojiMaxSize safely fetches the value for global configuration 'Cache.GTS.EmojiMaxSize' field +func GetCacheGTSEmojiMaxSize() int { return global.GetCacheGTSEmojiMaxSize() } + +// SetCacheGTSEmojiMaxSize safely sets the value for global configuration 'Cache.GTS.EmojiMaxSize' field +func SetCacheGTSEmojiMaxSize(v int) { global.SetCacheGTSEmojiMaxSize(v) } + +// GetCacheGTSEmojiTTL safely fetches the Configuration value for state's 'Cache.GTS.EmojiTTL' field +func (st *ConfigState) GetCacheGTSEmojiTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.EmojiTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSEmojiTTL safely sets the Configuration value for state's 'Cache.GTS.EmojiTTL' field +func (st *ConfigState) SetCacheGTSEmojiTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.EmojiTTL = v +	st.reloadToViper() +} + +// CacheGTSEmojiTTLFlag returns the flag name for the 'Cache.GTS.EmojiTTL' field +func CacheGTSEmojiTTLFlag() string { return "cache-gts-emoji-ttl" } + +// GetCacheGTSEmojiTTL safely fetches the value for global configuration 'Cache.GTS.EmojiTTL' field +func GetCacheGTSEmojiTTL() time.Duration { return global.GetCacheGTSEmojiTTL() } + +// SetCacheGTSEmojiTTL safely sets the value for global configuration 'Cache.GTS.EmojiTTL' field +func SetCacheGTSEmojiTTL(v time.Duration) { global.SetCacheGTSEmojiTTL(v) } + +// GetCacheGTSEmojiSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.EmojiSweepFreq' field +func (st *ConfigState) GetCacheGTSEmojiSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.EmojiSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSEmojiSweepFreq safely sets the Configuration value for state's 'Cache.GTS.EmojiSweepFreq' field +func (st *ConfigState) SetCacheGTSEmojiSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.EmojiSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSEmojiSweepFreqFlag returns the flag name for the 'Cache.GTS.EmojiSweepFreq' field +func CacheGTSEmojiSweepFreqFlag() string { return "cache-gts-emoji-sweep-freq" } + +// GetCacheGTSEmojiSweepFreq safely fetches the value for global configuration 'Cache.GTS.EmojiSweepFreq' field +func GetCacheGTSEmojiSweepFreq() time.Duration { return global.GetCacheGTSEmojiSweepFreq() } + +// SetCacheGTSEmojiSweepFreq safely sets the value for global configuration 'Cache.GTS.EmojiSweepFreq' field +func SetCacheGTSEmojiSweepFreq(v time.Duration) { global.SetCacheGTSEmojiSweepFreq(v) } + +// GetCacheGTSEmojiCategoryMaxSize safely fetches the Configuration value for state's 'Cache.GTS.EmojiCategoryMaxSize' field +func (st *ConfigState) GetCacheGTSEmojiCategoryMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.EmojiCategoryMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSEmojiCategoryMaxSize safely sets the Configuration value for state's 'Cache.GTS.EmojiCategoryMaxSize' field +func (st *ConfigState) SetCacheGTSEmojiCategoryMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.EmojiCategoryMaxSize = v +	st.reloadToViper() +} + +// CacheGTSEmojiCategoryMaxSizeFlag returns the flag name for the 'Cache.GTS.EmojiCategoryMaxSize' field +func CacheGTSEmojiCategoryMaxSizeFlag() string { return "cache-gts-emoji-category-max-size" } + +// GetCacheGTSEmojiCategoryMaxSize safely fetches the value for global configuration 'Cache.GTS.EmojiCategoryMaxSize' field +func GetCacheGTSEmojiCategoryMaxSize() int { return global.GetCacheGTSEmojiCategoryMaxSize() } + +// SetCacheGTSEmojiCategoryMaxSize safely sets the value for global configuration 'Cache.GTS.EmojiCategoryMaxSize' field +func SetCacheGTSEmojiCategoryMaxSize(v int) { global.SetCacheGTSEmojiCategoryMaxSize(v) } + +// GetCacheGTSEmojiCategoryTTL safely fetches the Configuration value for state's 'Cache.GTS.EmojiCategoryTTL' field +func (st *ConfigState) GetCacheGTSEmojiCategoryTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.EmojiCategoryTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSEmojiCategoryTTL safely sets the Configuration value for state's 'Cache.GTS.EmojiCategoryTTL' field +func (st *ConfigState) SetCacheGTSEmojiCategoryTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.EmojiCategoryTTL = v +	st.reloadToViper() +} + +// CacheGTSEmojiCategoryTTLFlag returns the flag name for the 'Cache.GTS.EmojiCategoryTTL' field +func CacheGTSEmojiCategoryTTLFlag() string { return "cache-gts-emoji-category-ttl" } + +// GetCacheGTSEmojiCategoryTTL safely fetches the value for global configuration 'Cache.GTS.EmojiCategoryTTL' field +func GetCacheGTSEmojiCategoryTTL() time.Duration { return global.GetCacheGTSEmojiCategoryTTL() } + +// SetCacheGTSEmojiCategoryTTL safely sets the value for global configuration 'Cache.GTS.EmojiCategoryTTL' field +func SetCacheGTSEmojiCategoryTTL(v time.Duration) { global.SetCacheGTSEmojiCategoryTTL(v) } + +// GetCacheGTSEmojiCategorySweepFreq safely fetches the Configuration value for state's 'Cache.GTS.EmojiCategorySweepFreq' field +func (st *ConfigState) GetCacheGTSEmojiCategorySweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.EmojiCategorySweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSEmojiCategorySweepFreq safely sets the Configuration value for state's 'Cache.GTS.EmojiCategorySweepFreq' field +func (st *ConfigState) SetCacheGTSEmojiCategorySweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.EmojiCategorySweepFreq = v +	st.reloadToViper() +} + +// CacheGTSEmojiCategorySweepFreqFlag returns the flag name for the 'Cache.GTS.EmojiCategorySweepFreq' field +func CacheGTSEmojiCategorySweepFreqFlag() string { return "cache-gts-emoji-category-sweep-freq" } + +// GetCacheGTSEmojiCategorySweepFreq safely fetches the value for global configuration 'Cache.GTS.EmojiCategorySweepFreq' field +func GetCacheGTSEmojiCategorySweepFreq() time.Duration { +	return global.GetCacheGTSEmojiCategorySweepFreq() +} + +// SetCacheGTSEmojiCategorySweepFreq safely sets the value for global configuration 'Cache.GTS.EmojiCategorySweepFreq' field +func SetCacheGTSEmojiCategorySweepFreq(v time.Duration) { global.SetCacheGTSEmojiCategorySweepFreq(v) } + +// GetCacheGTSMentionMaxSize safely fetches the Configuration value for state's 'Cache.GTS.MentionMaxSize' field +func (st *ConfigState) GetCacheGTSMentionMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.MentionMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSMentionMaxSize safely sets the Configuration value for state's 'Cache.GTS.MentionMaxSize' field +func (st *ConfigState) SetCacheGTSMentionMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.MentionMaxSize = v +	st.reloadToViper() +} + +// CacheGTSMentionMaxSizeFlag returns the flag name for the 'Cache.GTS.MentionMaxSize' field +func CacheGTSMentionMaxSizeFlag() string { return "cache-gts-mention-max-size" } + +// GetCacheGTSMentionMaxSize safely fetches the value for global configuration 'Cache.GTS.MentionMaxSize' field +func GetCacheGTSMentionMaxSize() int { return global.GetCacheGTSMentionMaxSize() } + +// SetCacheGTSMentionMaxSize safely sets the value for global configuration 'Cache.GTS.MentionMaxSize' field +func SetCacheGTSMentionMaxSize(v int) { global.SetCacheGTSMentionMaxSize(v) } + +// GetCacheGTSMentionTTL safely fetches the Configuration value for state's 'Cache.GTS.MentionTTL' field +func (st *ConfigState) GetCacheGTSMentionTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.MentionTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSMentionTTL safely sets the Configuration value for state's 'Cache.GTS.MentionTTL' field +func (st *ConfigState) SetCacheGTSMentionTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.MentionTTL = v +	st.reloadToViper() +} + +// CacheGTSMentionTTLFlag returns the flag name for the 'Cache.GTS.MentionTTL' field +func CacheGTSMentionTTLFlag() string { return "cache-gts-mention-ttl" } + +// GetCacheGTSMentionTTL safely fetches the value for global configuration 'Cache.GTS.MentionTTL' field +func GetCacheGTSMentionTTL() time.Duration { return global.GetCacheGTSMentionTTL() } + +// SetCacheGTSMentionTTL safely sets the value for global configuration 'Cache.GTS.MentionTTL' field +func SetCacheGTSMentionTTL(v time.Duration) { global.SetCacheGTSMentionTTL(v) } + +// GetCacheGTSMentionSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.MentionSweepFreq' field +func (st *ConfigState) GetCacheGTSMentionSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.MentionSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSMentionSweepFreq safely sets the Configuration value for state's 'Cache.GTS.MentionSweepFreq' field +func (st *ConfigState) SetCacheGTSMentionSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.MentionSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSMentionSweepFreqFlag returns the flag name for the 'Cache.GTS.MentionSweepFreq' field +func CacheGTSMentionSweepFreqFlag() string { return "cache-gts-mention-sweep-freq" } + +// GetCacheGTSMentionSweepFreq safely fetches the value for global configuration 'Cache.GTS.MentionSweepFreq' field +func GetCacheGTSMentionSweepFreq() time.Duration { return global.GetCacheGTSMentionSweepFreq() } + +// SetCacheGTSMentionSweepFreq safely sets the value for global configuration 'Cache.GTS.MentionSweepFreq' field +func SetCacheGTSMentionSweepFreq(v time.Duration) { global.SetCacheGTSMentionSweepFreq(v) } + +// GetCacheGTSNotificationMaxSize safely fetches the Configuration value for state's 'Cache.GTS.NotificationMaxSize' field +func (st *ConfigState) GetCacheGTSNotificationMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.NotificationMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSNotificationMaxSize safely sets the Configuration value for state's 'Cache.GTS.NotificationMaxSize' field +func (st *ConfigState) SetCacheGTSNotificationMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.NotificationMaxSize = v +	st.reloadToViper() +} + +// CacheGTSNotificationMaxSizeFlag returns the flag name for the 'Cache.GTS.NotificationMaxSize' field +func CacheGTSNotificationMaxSizeFlag() string { return "cache-gts-notification-max-size" } + +// GetCacheGTSNotificationMaxSize safely fetches the value for global configuration 'Cache.GTS.NotificationMaxSize' field +func GetCacheGTSNotificationMaxSize() int { return global.GetCacheGTSNotificationMaxSize() } + +// SetCacheGTSNotificationMaxSize safely sets the value for global configuration 'Cache.GTS.NotificationMaxSize' field +func SetCacheGTSNotificationMaxSize(v int) { global.SetCacheGTSNotificationMaxSize(v) } + +// GetCacheGTSNotificationTTL safely fetches the Configuration value for state's 'Cache.GTS.NotificationTTL' field +func (st *ConfigState) GetCacheGTSNotificationTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.NotificationTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSNotificationTTL safely sets the Configuration value for state's 'Cache.GTS.NotificationTTL' field +func (st *ConfigState) SetCacheGTSNotificationTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.NotificationTTL = v +	st.reloadToViper() +} + +// CacheGTSNotificationTTLFlag returns the flag name for the 'Cache.GTS.NotificationTTL' field +func CacheGTSNotificationTTLFlag() string { return "cache-gts-notification-ttl" } + +// GetCacheGTSNotificationTTL safely fetches the value for global configuration 'Cache.GTS.NotificationTTL' field +func GetCacheGTSNotificationTTL() time.Duration { return global.GetCacheGTSNotificationTTL() } + +// SetCacheGTSNotificationTTL safely sets the value for global configuration 'Cache.GTS.NotificationTTL' field +func SetCacheGTSNotificationTTL(v time.Duration) { global.SetCacheGTSNotificationTTL(v) } + +// GetCacheGTSNotificationSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.NotificationSweepFreq' field +func (st *ConfigState) GetCacheGTSNotificationSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.NotificationSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSNotificationSweepFreq safely sets the Configuration value for state's 'Cache.GTS.NotificationSweepFreq' field +func (st *ConfigState) SetCacheGTSNotificationSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.NotificationSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSNotificationSweepFreqFlag returns the flag name for the 'Cache.GTS.NotificationSweepFreq' field +func CacheGTSNotificationSweepFreqFlag() string { return "cache-gts-notification-sweep-freq" } + +// GetCacheGTSNotificationSweepFreq safely fetches the value for global configuration 'Cache.GTS.NotificationSweepFreq' field +func GetCacheGTSNotificationSweepFreq() time.Duration { +	return global.GetCacheGTSNotificationSweepFreq() +} + +// SetCacheGTSNotificationSweepFreq safely sets the value for global configuration 'Cache.GTS.NotificationSweepFreq' field +func SetCacheGTSNotificationSweepFreq(v time.Duration) { global.SetCacheGTSNotificationSweepFreq(v) } + +// GetCacheGTSStatusMaxSize safely fetches the Configuration value for state's 'Cache.GTS.StatusMaxSize' field +func (st *ConfigState) GetCacheGTSStatusMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.StatusMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSStatusMaxSize safely sets the Configuration value for state's 'Cache.GTS.StatusMaxSize' field +func (st *ConfigState) SetCacheGTSStatusMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.StatusMaxSize = v +	st.reloadToViper() +} + +// CacheGTSStatusMaxSizeFlag returns the flag name for the 'Cache.GTS.StatusMaxSize' field +func CacheGTSStatusMaxSizeFlag() string { return "cache-gts-status-max-size" } + +// GetCacheGTSStatusMaxSize safely fetches the value for global configuration 'Cache.GTS.StatusMaxSize' field +func GetCacheGTSStatusMaxSize() int { return global.GetCacheGTSStatusMaxSize() } + +// SetCacheGTSStatusMaxSize safely sets the value for global configuration 'Cache.GTS.StatusMaxSize' field +func SetCacheGTSStatusMaxSize(v int) { global.SetCacheGTSStatusMaxSize(v) } + +// GetCacheGTSStatusTTL safely fetches the Configuration value for state's 'Cache.GTS.StatusTTL' field +func (st *ConfigState) GetCacheGTSStatusTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.StatusTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSStatusTTL safely sets the Configuration value for state's 'Cache.GTS.StatusTTL' field +func (st *ConfigState) SetCacheGTSStatusTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.StatusTTL = v +	st.reloadToViper() +} + +// CacheGTSStatusTTLFlag returns the flag name for the 'Cache.GTS.StatusTTL' field +func CacheGTSStatusTTLFlag() string { return "cache-gts-status-ttl" } + +// GetCacheGTSStatusTTL safely fetches the value for global configuration 'Cache.GTS.StatusTTL' field +func GetCacheGTSStatusTTL() time.Duration { return global.GetCacheGTSStatusTTL() } + +// SetCacheGTSStatusTTL safely sets the value for global configuration 'Cache.GTS.StatusTTL' field +func SetCacheGTSStatusTTL(v time.Duration) { global.SetCacheGTSStatusTTL(v) } + +// GetCacheGTSStatusSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.StatusSweepFreq' field +func (st *ConfigState) GetCacheGTSStatusSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.StatusSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSStatusSweepFreq safely sets the Configuration value for state's 'Cache.GTS.StatusSweepFreq' field +func (st *ConfigState) SetCacheGTSStatusSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.StatusSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSStatusSweepFreqFlag returns the flag name for the 'Cache.GTS.StatusSweepFreq' field +func CacheGTSStatusSweepFreqFlag() string { return "cache-gts-status-sweep-freq" } + +// GetCacheGTSStatusSweepFreq safely fetches the value for global configuration 'Cache.GTS.StatusSweepFreq' field +func GetCacheGTSStatusSweepFreq() time.Duration { return global.GetCacheGTSStatusSweepFreq() } + +// SetCacheGTSStatusSweepFreq safely sets the value for global configuration 'Cache.GTS.StatusSweepFreq' field +func SetCacheGTSStatusSweepFreq(v time.Duration) { global.SetCacheGTSStatusSweepFreq(v) } + +// GetCacheGTSTombstoneMaxSize safely fetches the Configuration value for state's 'Cache.GTS.TombstoneMaxSize' field +func (st *ConfigState) GetCacheGTSTombstoneMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.TombstoneMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSTombstoneMaxSize safely sets the Configuration value for state's 'Cache.GTS.TombstoneMaxSize' field +func (st *ConfigState) SetCacheGTSTombstoneMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.TombstoneMaxSize = v +	st.reloadToViper() +} + +// CacheGTSTombstoneMaxSizeFlag returns the flag name for the 'Cache.GTS.TombstoneMaxSize' field +func CacheGTSTombstoneMaxSizeFlag() string { return "cache-gts-tombstone-max-size" } + +// GetCacheGTSTombstoneMaxSize safely fetches the value for global configuration 'Cache.GTS.TombstoneMaxSize' field +func GetCacheGTSTombstoneMaxSize() int { return global.GetCacheGTSTombstoneMaxSize() } + +// SetCacheGTSTombstoneMaxSize safely sets the value for global configuration 'Cache.GTS.TombstoneMaxSize' field +func SetCacheGTSTombstoneMaxSize(v int) { global.SetCacheGTSTombstoneMaxSize(v) } + +// GetCacheGTSTombstoneTTL safely fetches the Configuration value for state's 'Cache.GTS.TombstoneTTL' field +func (st *ConfigState) GetCacheGTSTombstoneTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.TombstoneTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSTombstoneTTL safely sets the Configuration value for state's 'Cache.GTS.TombstoneTTL' field +func (st *ConfigState) SetCacheGTSTombstoneTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.TombstoneTTL = v +	st.reloadToViper() +} + +// CacheGTSTombstoneTTLFlag returns the flag name for the 'Cache.GTS.TombstoneTTL' field +func CacheGTSTombstoneTTLFlag() string { return "cache-gts-tombstone-ttl" } + +// GetCacheGTSTombstoneTTL safely fetches the value for global configuration 'Cache.GTS.TombstoneTTL' field +func GetCacheGTSTombstoneTTL() time.Duration { return global.GetCacheGTSTombstoneTTL() } + +// SetCacheGTSTombstoneTTL safely sets the value for global configuration 'Cache.GTS.TombstoneTTL' field +func SetCacheGTSTombstoneTTL(v time.Duration) { global.SetCacheGTSTombstoneTTL(v) } + +// GetCacheGTSTombstoneSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.TombstoneSweepFreq' field +func (st *ConfigState) GetCacheGTSTombstoneSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.TombstoneSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSTombstoneSweepFreq safely sets the Configuration value for state's 'Cache.GTS.TombstoneSweepFreq' field +func (st *ConfigState) SetCacheGTSTombstoneSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.TombstoneSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSTombstoneSweepFreqFlag returns the flag name for the 'Cache.GTS.TombstoneSweepFreq' field +func CacheGTSTombstoneSweepFreqFlag() string { return "cache-gts-tombstone-sweep-freq" } + +// GetCacheGTSTombstoneSweepFreq safely fetches the value for global configuration 'Cache.GTS.TombstoneSweepFreq' field +func GetCacheGTSTombstoneSweepFreq() time.Duration { return global.GetCacheGTSTombstoneSweepFreq() } + +// SetCacheGTSTombstoneSweepFreq safely sets the value for global configuration 'Cache.GTS.TombstoneSweepFreq' field +func SetCacheGTSTombstoneSweepFreq(v time.Duration) { global.SetCacheGTSTombstoneSweepFreq(v) } + +// GetCacheGTSUserMaxSize safely fetches the Configuration value for state's 'Cache.GTS.UserMaxSize' field +func (st *ConfigState) GetCacheGTSUserMaxSize() (v int) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.UserMaxSize +	st.mutex.Unlock() +	return +} + +// SetCacheGTSUserMaxSize safely sets the Configuration value for state's 'Cache.GTS.UserMaxSize' field +func (st *ConfigState) SetCacheGTSUserMaxSize(v int) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.UserMaxSize = v +	st.reloadToViper() +} + +// CacheGTSUserMaxSizeFlag returns the flag name for the 'Cache.GTS.UserMaxSize' field +func CacheGTSUserMaxSizeFlag() string { return "cache-gts-user-max-size" } + +// GetCacheGTSUserMaxSize safely fetches the value for global configuration 'Cache.GTS.UserMaxSize' field +func GetCacheGTSUserMaxSize() int { return global.GetCacheGTSUserMaxSize() } + +// SetCacheGTSUserMaxSize safely sets the value for global configuration 'Cache.GTS.UserMaxSize' field +func SetCacheGTSUserMaxSize(v int) { global.SetCacheGTSUserMaxSize(v) } + +// GetCacheGTSUserTTL safely fetches the Configuration value for state's 'Cache.GTS.UserTTL' field +func (st *ConfigState) GetCacheGTSUserTTL() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.UserTTL +	st.mutex.Unlock() +	return +} + +// SetCacheGTSUserTTL safely sets the Configuration value for state's 'Cache.GTS.UserTTL' field +func (st *ConfigState) SetCacheGTSUserTTL(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.UserTTL = v +	st.reloadToViper() +} + +// CacheGTSUserTTLFlag returns the flag name for the 'Cache.GTS.UserTTL' field +func CacheGTSUserTTLFlag() string { return "cache-gts-user-ttl" } + +// GetCacheGTSUserTTL safely fetches the value for global configuration 'Cache.GTS.UserTTL' field +func GetCacheGTSUserTTL() time.Duration { return global.GetCacheGTSUserTTL() } + +// SetCacheGTSUserTTL safely sets the value for global configuration 'Cache.GTS.UserTTL' field +func SetCacheGTSUserTTL(v time.Duration) { global.SetCacheGTSUserTTL(v) } + +// GetCacheGTSUserSweepFreq safely fetches the Configuration value for state's 'Cache.GTS.UserSweepFreq' field +func (st *ConfigState) GetCacheGTSUserSweepFreq() (v time.Duration) { +	st.mutex.Lock() +	v = st.config.Cache.GTS.UserSweepFreq +	st.mutex.Unlock() +	return +} + +// SetCacheGTSUserSweepFreq safely sets the Configuration value for state's 'Cache.GTS.UserSweepFreq' field +func (st *ConfigState) SetCacheGTSUserSweepFreq(v time.Duration) { +	st.mutex.Lock() +	defer st.mutex.Unlock() +	st.config.Cache.GTS.UserSweepFreq = v +	st.reloadToViper() +} + +// CacheGTSUserSweepFreqFlag returns the flag name for the 'Cache.GTS.UserSweepFreq' field +func CacheGTSUserSweepFreqFlag() string { return "cache-gts-user-sweep-freq" } + +// GetCacheGTSUserSweepFreq safely fetches the value for global configuration 'Cache.GTS.UserSweepFreq' field +func GetCacheGTSUserSweepFreq() time.Duration { return global.GetCacheGTSUserSweepFreq() } + +// SetCacheGTSUserSweepFreq safely sets the value for global configuration 'Cache.GTS.UserSweepFreq' field +func SetCacheGTSUserSweepFreq(v time.Duration) { global.SetCacheGTSUserSweepFreq(v) } +  // GetAdminAccountUsername safely fetches the Configuration value for state's 'AdminAccountUsername' field  func (st *ConfigState) GetAdminAccountUsername() (v string) {  	st.mutex.Lock() @@ -1944,4 +2702,3 @@ func GetAdminMediaPruneDryRun() bool { return global.GetAdminMediaPruneDryRun()  // SetAdminMediaPruneDryRun safely sets the value for global configuration 'AdminMediaPruneDryRun' field  func SetAdminMediaPruneDryRun(v bool) { global.SetAdminMediaPruneDryRun(v) } - diff --git a/internal/config/state.go b/internal/config/state.go index 17fd31e2a..64d87d771 100644 --- a/internal/config/state.go +++ b/internal/config/state.go @@ -41,8 +41,8 @@ func NewState() *ConfigState {  	viper := viper.New()  	// Flag 'some-flag-name' becomes env var 'GTS_SOME_FLAG_NAME' -	viper.SetEnvPrefix("gts")  	viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) +	viper.SetEnvPrefix("gts")  	// Load appropriate named vals from env  	viper.AutomaticEnv() @@ -132,9 +132,13 @@ func (st *ConfigState) reloadToViper() {  func (st *ConfigState) reloadFromViper() {  	if err := st.viper.Unmarshal(&st.config, func(c *mapstructure.DecoderConfig) {  		c.TagName = "name" -		c.ZeroFields = true // empty the config struct before we marshal values into it + +		// empty config before marshaling +		c.ZeroFields = true  		oldhook := c.DecodeHook + +		// Use the TextUnmarshaler interface when decoding.  		c.DecodeHook = mapstructure.ComposeDecodeHookFunc(  			mapstructure.TextUnmarshallerHookFunc(),  			oldhook, diff --git a/internal/config/testdata/test.yaml b/internal/config/testdata/test.yaml index 9a57b589d..3b2b63fe2 100644 --- a/internal/config/testdata/test.yaml +++ b/internal/config/testdata/test.yaml @@ -409,3 +409,10 @@ syslog-protocol: "udp"  # String. Address:port to send syslog logs to. Leave empty to connect to local syslog.  # Default: "localhost:514"  syslog-address: "localhost:514" + +# Cache configuration +cache: +  gts: +    account-max-size: 99 +    account-ttl: "3h" +    account-sweep-freq: "1s"
\ No newline at end of file | 
