summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorKyren223 <ulmliad223@gmail.com>2024-10-25 11:52:31 +0300
committerKyren223 <ulmliad223@gmail.com>2024-10-25 11:52:31 +0300
commit7e1fded9b559856c63e14f953244d938507a2632 (patch)
treeb1f4c6bbb9097de7b3ef030e19b5b58eec199d95 /internal
parentd294b53e68f02f4aae98fc3f2133c7696706bf0b (diff)
feat: add per-request-type server timeout
Diffstat (limited to 'internal')
-rw-r--r--internal/server/api/api.go1
-rw-r--r--internal/server/server.go27
2 files changed, 27 insertions, 1 deletions
diff --git a/internal/server/api/api.go b/internal/server/api/api.go
index 4596cdb..cf072f3 100644
--- a/internal/server/api/api.go
+++ b/internal/server/api/api.go
@@ -30,6 +30,7 @@ func SendMessage(ctx context.Context, request *packet.SendMessage) packet.Payloa
messages = append(messages, message)
+ // TODO: broadcast message
payload := &packet.Messages{Messages: messages}
pkt := packet.NewPacket(packet.NewMsgPackEncoder(payload))
sess.WriteQueue <- pkt
diff --git a/internal/server/server.go b/internal/server/server.go
index ab88bd1..7805e27 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -292,8 +292,33 @@ func processRequest(ctx context.Context, request packet.Payload) packet.Payload
switch request := request.(type) {
case *packet.SendMessage:
- return api.SendMessage(ctx, request)
+ return timeout(100 * time.Millisecond, api.SendMessage, ctx, request)
default:
return &packet.ErrorMessage{Error: "use of unsupported packet type"}
}
}
+
+func timeout[T packet.Payload](
+ timeoutDuration time.Duration,
+ apiRequest func(context.Context, T) packet.Payload,
+ ctx context.Context, request T,
+) packet.Payload {
+ responseChan := make(chan packet.Payload)
+ ctx, cancel := context.WithTimeout(ctx, timeoutDuration)
+ defer cancel()
+
+ go func() {
+ responseChan <- apiRequest(ctx, request)
+ }()
+
+ select {
+ case response := <-responseChan:
+ return response
+ case <-ctx.Done():
+ sess, ok := session.FromContext(ctx)
+ assert.Assert(ok, "session should exist")
+ log.Println(sess.Addr(), "timeout of", request.Type(), "request")
+ // TODO: consider if we want to say it's a timeout or be vague to mitigate DOS attacks
+ return &packet.ErrorMessage{Error: "internal server error"}
+ }
+}