diff options
| author | Kyren223 <ulmliad223@gmail.com> | 2024-10-25 11:52:31 +0300 |
|---|---|---|
| committer | Kyren223 <ulmliad223@gmail.com> | 2024-10-25 11:52:31 +0300 |
| commit | 7e1fded9b559856c63e14f953244d938507a2632 (patch) | |
| tree | b1f4c6bbb9097de7b3ef030e19b5b58eec199d95 /internal/server | |
| parent | d294b53e68f02f4aae98fc3f2133c7696706bf0b (diff) | |
feat: add per-request-type server timeout
Diffstat (limited to 'internal/server')
| -rw-r--r-- | internal/server/api/api.go | 1 | ||||
| -rw-r--r-- | internal/server/server.go | 27 |
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"} + } +} |
