mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-22 11:27:28 -06:00
[feature] Add instance-stats-randomize config option (#3718)
* [feature] Add `instance-stats-randomize` config option * don't use cache (overkill)
This commit is contained in:
parent
c47b9bd1d1
commit
a55bd6d2bd
13 changed files with 183 additions and 10 deletions
|
|
@ -18,10 +18,17 @@
|
|||
package typeutils
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/interaction"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/filter/visibility"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/log"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||
)
|
||||
|
||||
|
|
@ -31,6 +38,7 @@ type Converter struct {
|
|||
randAvatars sync.Map
|
||||
visFilter *visibility.Filter
|
||||
intFilter *interaction.Filter
|
||||
randStats atomic.Pointer[apimodel.RandomStats]
|
||||
}
|
||||
|
||||
func NewConverter(state *state.State) *Converter {
|
||||
|
|
@ -41,3 +49,53 @@ func NewConverter(state *state.State) *Converter {
|
|||
intFilter: interaction.NewFilter(state),
|
||||
}
|
||||
}
|
||||
|
||||
// RandomStats returns or generates
|
||||
// and returns random instance stats.
|
||||
func (c *Converter) RandomStats() apimodel.RandomStats {
|
||||
now := time.Now()
|
||||
stats := c.randStats.Load()
|
||||
if stats != nil && time.Since(stats.Generated) < time.Hour {
|
||||
// Random stats are still
|
||||
// fresh (less than 1hr old),
|
||||
// so return them as-is.
|
||||
return *stats
|
||||
}
|
||||
|
||||
// Generate new random stats.
|
||||
newStats := genRandStats()
|
||||
newStats.Generated = now
|
||||
c.randStats.Store(&newStats)
|
||||
return newStats
|
||||
}
|
||||
|
||||
func genRandStats() apimodel.RandomStats {
|
||||
const (
|
||||
statusesMax = 10000000
|
||||
usersMax = 1000000
|
||||
)
|
||||
|
||||
statusesB, err := crand.Int(crand.Reader, big.NewInt(statusesMax))
|
||||
if err != nil {
|
||||
// Only errs if something is buggered with the OS.
|
||||
log.Panicf(nil, "error randomly generating statuses count: %v", err)
|
||||
}
|
||||
|
||||
totalUsersB, err := crand.Int(crand.Reader, big.NewInt(usersMax))
|
||||
if err != nil {
|
||||
// Only errs if something is buggered with the OS.
|
||||
log.Panicf(nil, "error randomly generating users count: %v", err)
|
||||
}
|
||||
|
||||
// Monthly users should only ever
|
||||
// be <= 100% of total users.
|
||||
totalUsers := totalUsersB.Int64()
|
||||
activeRatio := rand.Float64() //nolint
|
||||
mau := int64(float64(totalUsers) * activeRatio)
|
||||
|
||||
return apimodel.RandomStats{
|
||||
Statuses: statusesB.Int64(),
|
||||
TotalUsers: totalUsers,
|
||||
MonthlyActiveUsers: mau,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1745,6 +1745,12 @@ func (c *Converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
stats["domain_count"] = util.Ptr(domainCount)
|
||||
instance.Stats = stats
|
||||
|
||||
if config.GetInstanceStatsRandomize() {
|
||||
// Whack some random stats on the instance
|
||||
// to be injected by API handlers.
|
||||
instance.RandomStats = c.RandomStats()
|
||||
}
|
||||
|
||||
// thumbnail
|
||||
iAccount, err := c.state.DB.GetInstanceAccount(ctx, "")
|
||||
if err != nil {
|
||||
|
|
@ -1821,6 +1827,12 @@ func (c *Converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
instance.Debug = util.Ptr(true)
|
||||
}
|
||||
|
||||
if config.GetInstanceStatsRandomize() {
|
||||
// Whack some random stats on the instance
|
||||
// to be injected by API handlers.
|
||||
instance.RandomStats = c.RandomStats()
|
||||
}
|
||||
|
||||
// thumbnail
|
||||
thumbnail := apimodel.InstanceV2Thumbnail{}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue