Commit ac6eaa67 authored by Andrei Mihu's avatar Andrei Mihu
Browse files

Improve timeout handling in JS/Lua runtime Nakama module HTTP requests.

parent eed5c3cf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ The format is based on [keep a changelog](http://keepachangelog.com) and this pr
- Ensure corresponding leaderboard rank cache entries are removed when a user is deleted.
- Consistently update scheduler when leaderboards and tournaments are deleted.
- Fix matchmaker tracking of eligible matches when downsizing for count multiples.
- Correct handling of `httpRequest` calls in the JavaScript runtime Nakama module.
- Correct handling of `httpRequest` calls in the Lua runtime Nakama module.

## [3.14.0] - 2022-10-14
### Added
+10 −7
Original line number Diff line number Diff line
@@ -103,9 +103,7 @@ func NewRuntimeJavascriptNakamaModule(logger *zap.Logger, db *sql.DB, protojsonM
		rankCache:            rankCache,
		localCache:           localCache,
		leaderboardScheduler: leaderboardScheduler,
		httpClient: &http.Client{
			Timeout: 5 * time.Second,
		},
		httpClient:           &http.Client{},

		node:          config.GetName(),
		eventFn:       eventFn,
@@ -572,12 +570,14 @@ func (n *runtimeJavascriptNakamaModule) httpRequest(r *goja.Runtime) func(goja.F
			body = getJsString(r, f.Argument(3))
		}

		var timeoutMs int64
		timeoutArg := f.Argument(4)
		if timeoutArg != goja.Undefined() && timeoutArg != goja.Null() {
			n.httpClient.Timeout = time.Duration(timeoutArg.ToInteger()) * time.Millisecond
			timeoutMs = timeoutArg.ToInteger()
		}
		if timeoutMs <= 0 {
			timeoutMs = 5_000
		}

		n.logger.Debug(fmt.Sprintf("Http Timeout: %v", n.httpClient.Timeout))

		if url == "" {
			panic(r.NewTypeError("URL string cannot be empty."))
@@ -592,7 +592,10 @@ func (n *runtimeJavascriptNakamaModule) httpRequest(r *goja.Runtime) func(goja.F
			requestBody = strings.NewReader(body)
		}

		req, err := http.NewRequest(method, url, requestBody)
		ctx, ctxCancelFn := context.WithTimeout(n.ctx, time.Duration(timeoutMs)*time.Millisecond)
		defer ctxCancelFn()

		req, err := http.NewRequestWithContext(ctx, method, url, requestBody)
		if err != nil {
			panic(r.NewGoError(fmt.Errorf("HTTP request is invalid: %v", err.Error())))
		}
+10 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ package server

import (
	"bytes"
	"context"
	"crypto"
	"crypto/aes"
	"crypto/cipher"
@@ -111,9 +112,7 @@ func NewRuntimeLuaNakamaModule(logger *zap.Logger, db *sql.DB, protojsonMarshale
		localCache:           localCache,
		registerCallbackFn:   registerCallbackFn,
		announceCallbackFn:   announceCallbackFn,
		client: &http.Client{
			Timeout: 5 * time.Second,
		},
		client:               &http.Client{},

		node:          config.GetName(),
		matchCreateFn: matchCreateFn,
@@ -937,15 +936,21 @@ func (n *RuntimeLuaNakamaModule) httpRequest(l *lua.LState) int {

	// Set a custom timeout if one is provided, or use the default.
	timeoutMs := l.OptInt64(5, 5000)
	n.client.Timeout = time.Duration(timeoutMs) * time.Millisecond
	if timeoutMs <= 0 {
		timeoutMs = 5_000
	}

	// Prepare request body, if any.
	var requestBody io.Reader
	if body != "" {
		requestBody = strings.NewReader(body)
	}

	ctx, ctxCancelFn := context.WithTimeout(l.Context(), time.Duration(timeoutMs)*time.Millisecond)
	defer ctxCancelFn()

	// Prepare the request.
	req, err := http.NewRequest(method, url, requestBody)
	req, err := http.NewRequestWithContext(ctx, method, url, requestBody)
	if err != nil {
		l.RaiseError("HTTP request error: %v", err.Error())
		return 0