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
17 changes: 17 additions & 0 deletions backend/logic/puzzles.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

func GetRandomPuzzle() (*PuzzleDto, error){
dat, err := mongo.MongoFindRandPuzzle()

if err != nil {
return &PuzzleDto{}, errors.New("Could not find a random puzzle.")
}
Expand All @@ -17,6 +18,22 @@ func GetRandomPuzzle() (*PuzzleDto, error){
return pdto, nil
}

func GetUniquePlayersMetric(){
dat, err := mongo.GetUniquePlayers()
if err != nil {
return;
}
go prometheus.PublishWithValue("unique", int(dat))
}

func GetTotalNumberOfSolvesMetric(){
dat, err := mongo.GetTotalNumberOfSolves()
if err != nil {
return;
}
go prometheus.PublishWithValue("grandsolve", int(dat))
}

func PuzzleToJson(puzzle PuzzleDto) ([]byte, error){
dat, err := puzzle.ToJson()
if err != nil {
Expand Down
15 changes: 14 additions & 1 deletion backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"net/http"
"embed"
"io/fs"
_"time"
"time"
"errors"
"log"

Expand Down Expand Up @@ -152,5 +152,18 @@ func main(){
go func() {
log.Fatal(prometheus.BuildServer())
}()

//cron jobs
go func() {
ticker := time.NewTicker(5 * time.Second)
for {
select {
case _ = <-ticker.C:
logic.GetUniquePlayersMetric()
//logic.GetTotalNumberOfSolvesMetric()
}
}
}()

for {}
}
72 changes: 72 additions & 0 deletions backend/mongo/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,76 @@ func MarkAsSeen(pid string, uuid string) {
if err != nil {
fmt.Println("[ERROR] could not increment solvecount for",pid," because:" , err)
}
}

func GetUniquePlayers() (int32, error){

defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered. Error:\n", r)
}
}()

coll := client.Database(dbname).Collection("puzzles")

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

var result []bson.M
filter := mongo.Pipeline{
{{"$unwind", "$seencount"}},
{{"$group", bson.D{{"_id", "$seencount"}}}},
{{"$count", "uniqueUUIDs"}},
}

cursor, err := coll.Aggregate(ctx,filter)
if err != nil {
fmt.Println("[ERROR] could not get value from GetUniquePlayers()" , err)
return -1, errors.New("could not get value from GetUniquePlayers()")
}
if err = cursor.All(ctx, &result); err != nil {
fmt.Println("[ERROR] could not extract random puzzle from result because:", err)
return -1, errors.New("could not extract random puzzle from result")
}

if len(result) == 0 {return -1, errors.New("could not find any result")}

return result[0]["uniqueUUIDs"].(int32), nil
}

func GetTotalNumberOfSolves() (int32, error){

defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered. Error:\n", r)
}
}()

coll := client.Database(dbname).Collection("puzzles")

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

var result []bson.M
filter := []bson.M{
{
"$group": bson.M{
"_id": "",
"solvecount": bson.M{"$sum": "$solvecount"},
},
},
}
cursor, err := coll.Aggregate(ctx,filter)
if err != nil {
fmt.Println("[ERROR] could not get value from GetTotalNumberOfSolves()" , err)
return -1, errors.New("could not get value from GetTotalNumberOfSolves()")
}
if err = cursor.All(ctx, &result); err != nil {
fmt.Println("[ERROR] could not extract random puzzle from result because:", err)
return -1, errors.New("could not extract random puzzle from result")
}

if len(result) == 0 {return -1, errors.New("could not find any result")}

return result[0]["solvecount"].(int32), nil
}
31 changes: 31 additions & 0 deletions backend/prometheus/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,29 @@ var (
},
[]string{"value"},
)
numberOfUniqueUsers = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "number_of_unique_users",
Help: "Number of unique users that visited the site",
},
[]string{"value"},
)
grandSolveTotal = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "number_of_all_solves",
Help: "Number of all solves of all puzzles together",
},
[]string{"value"},
)
)

var (
root = make(chan int, 1000)
load = make(chan int, 1000)
seen = make(chan int, 1000)
solved = make(chan int, 1000)
unique = make(chan int)
grandsolve = make(chan int)
)

func Publish(ack_type string){
Expand All @@ -58,6 +74,15 @@ func Publish(ack_type string){
}
}

func PublishWithValue(ack_type string, aa int){
switch ack_type {
case "unique":
unique <- aa
case "grandsolve":
grandsolve <- aa
}
}

func ExecLoop(){
for{
select {
Expand All @@ -69,6 +94,10 @@ func ExecLoop(){
totalSeen.WithLabelValues("value").Inc()
case _= <- solved:
totalSolved.WithLabelValues("value").Inc()
case un := <- unique:
numberOfUniqueUsers.WithLabelValues("value").Set(float64(un))
case gs := <- grandsolve:
grandSolveTotal.WithLabelValues("value").Set(float64(gs))
}
}
}
Expand All @@ -79,6 +108,8 @@ func BuildServer() error{
prometheus.MustRegister(totalLoad)
prometheus.MustRegister(totalSeen)
prometheus.MustRegister(totalSolved)
prometheus.MustRegister(numberOfUniqueUsers)
prometheus.MustRegister(grandSolveTotal)

go ExecLoop()

Expand Down
2 changes: 1 addition & 1 deletion backend/views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
</div>
<footer class="main-footer">
<div class="footer-left">
v1.1 <div class="bullet"></div> Copyright &copy; 2025 <div class="bullet"></div> Made with love By <a target="_blank"
v1.2 <div class="bullet"></div> Copyright &copy; 2025 <div class="bullet"></div> Made with love By <a target="_blank"
href="https://x.com/AhmedDebb">Ahmed
Debbech</a>
</div>
Expand Down