/
server.go
151 lines (143 loc) · 4.12 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package entities
import (
"context"
"encoding/json"
"github.com/discordextremelist/api/util"
"github.com/getsentry/sentry-go"
log "github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"time"
)
type ServerLinks struct {
Invite string `json:"invite,omitempty"`
Website string `json:"website"`
Donation string `json:"donation"`
}
type ServerStatus struct {
ReviewRequired bool `json:"reviewRequired"`
}
type Server struct {
MongoID string `json:"_id,omitempty"`
ID string `bson:"_id" json:"id"`
InviteCode string `json:"inviteCode,omitempty"`
Name string `json:"name"`
ShortDesc string `json:"shortDesc"`
LongDesc string `json:"longDesc"`
Tags []string `json:"tags"`
PreviewChannel string `json:"previewChannel"`
Owner Owner `json:"owner"`
Icon Avatar `json:"icon"`
Links ServerLinks `json:"links"`
Status ServerStatus `json:"status"`
}
func CleanupServer(rank UserRank, server *Server) *Server {
copied := *server
copied.InviteCode = ""
copied.Links.Invite = ""
if rank.Admin || rank.Assistant {
copied.InviteCode = server.InviteCode
copied.Links.Invite = server.Links.Invite
}
return &copied
}
func mongoLookupServer(id string) (error, *Server) {
findStart := time.Now()
var findEnd int64
res := util.Database.Mongo.Collection("servers").FindOne(context.TODO(), bson.M{"_id": id})
if res.Err() != nil {
AddMongoLookupTime("servers", id, time.Since(findStart).Microseconds(), -1)
return res.Err(), nil
}
findEnd = time.Since(findStart).Microseconds()
server := Server{}
decodeStart := time.Now()
var decodeEnd int64
if err := res.Decode(&server); err != nil {
sentry.CaptureException(err)
AddMongoLookupTime("servers", id, findEnd, time.Since(decodeStart).Microseconds())
return err, nil
}
decodeEnd = time.Since(decodeStart).Microseconds()
AddMongoLookupTime("servers", id, findEnd, decodeEnd)
return nil, &server
}
func LookupServer(id string, clean bool) (error, *Server) {
findStart := time.Now()
var findEnd int64
redisServer, err := util.Database.Redis.HGet(context.TODO(), "servers", id).Result()
if err == nil {
findEnd = time.Since(findStart).Microseconds()
if redisServer == "" {
err, server := mongoLookupServer(id)
if err != nil {
if err == mongo.ErrNoDocuments {
return err, nil
}
sentry.CaptureException(err)
log.Errorf("Fallback for MongoDB failed for LookupServer(%s): %v", id, err.Error())
return LookupError, nil
} else {
server.MongoID = ""
if clean {
server = CleanupServer(fakeRank, server)
}
return nil, server
}
}
server := &Server{}
decodeStart := time.Now()
err = json.Unmarshal([]byte(redisServer), &server)
if err != nil {
sentry.CaptureException(err)
AddRedisLookupTime("servers", id, findEnd, time.Since(decodeStart).Microseconds())
log.Errorf("Json parsing failed for LookupServer(%s): %v", id, err.Error())
return LookupError, nil
} else {
if server.ID == "" {
server.ID = server.MongoID
server.MongoID = ""
} else {
server.MongoID = ""
}
if clean {
server = CleanupServer(fakeRank, server)
}
AddRedisLookupTime("servers", id, findEnd, time.Since(decodeStart).Microseconds())
return nil, server
}
} else {
err, server := mongoLookupServer(id)
if err != nil {
if err == mongo.ErrNoDocuments {
return err, nil
}
sentry.CaptureException(err)
log.Errorf("Fallback for MongoDB failed for LookupServer(%s): %v", id, err.Error())
return LookupError, nil
} else {
server.MongoID = ""
if clean {
server = CleanupServer(fakeRank, server)
}
return nil, server
}
}
}
func GetAllServers(clean bool) (error, []Server) {
redisServers := util.Scan[Server]("servers")
var actual []Server
for _, server := range redisServers {
if server.ID == "" {
server.ID = server.MongoID
server.MongoID = ""
} else {
server.MongoID = ""
}
if clean {
server = *CleanupServer(fakeRank, &server)
}
actual = append(actual, server)
}
return nil, actual
}