diff --git a/CHANGELOG.md b/CHANGELOG.md index cf06312d..fc1c2e4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v0.38.2 (WIP) + +- Added `RealtimeConnectRequestEvent.MaxTimeout` field to specify the absolute max duration a realtime connection can remain open (default to 30mins). + _This is in addition to the `IdeTimeout` of 5mins in order to prevent misuse and to allow the GC to run more regularly._ + +- (@todo) Updated all `golang.org/x/` packages containing the [recent security fixes](https://groups.google.com/g/golang-announce/c/PdiGK3xulk4). + + ## v0.38.1 - Silenced the superuser IPs confirmation if there is no change. diff --git a/apis/realtime.go b/apis/realtime.go index 85a45eff..c490c1c3 100644 --- a/apis/realtime.go +++ b/apis/realtime.go @@ -65,6 +65,7 @@ func realtimeConnect(e *core.RequestEvent) error { connectEvent.RequestEvent = e connectEvent.Client = subscriptions.NewDefaultClient() connectEvent.IdleTimeout = 5 * time.Minute + connectEvent.MaxTimeout = 30 * time.Minute return e.App.OnRealtimeConnectRequest().Trigger(connectEvent, func(ce *core.RealtimeConnectRequestEvent) error { // register new subscription client @@ -99,12 +100,19 @@ func realtimeConnect(e *core.RequestEvent) error { return nil } + // start a max lifetime timer to prevent accumulating too much + // connection resources and to allow the GC to run more regularly + maxTimer := time.NewTimer(ce.MaxTimeout) + defer maxTimer.Stop() + // start an idle timer to keep track of inactive/forgotten connections idleTimer := time.NewTimer(ce.IdleTimeout) defer idleTimer.Stop() for { select { + case <-maxTimer.C: + cancelRequest() case <-idleTimer.C: cancelRequest() case msg, ok := <-ce.Client.Channel(): diff --git a/core/events.go b/core/events.go index f0da6ea2..efb22664 100644 --- a/core/events.go +++ b/core/events.go @@ -448,8 +448,24 @@ type RealtimeConnectRequestEvent struct { Client subscriptions.Client - // note: modifying it after the connect has no effect + // IdleTimeout specifies the max duration to wait for a new message + // before closing the connection. + // + // Modifying the value after the connection has been established has no effect. + // + // Defaults to 5 minutes. IdleTimeout time.Duration + + // MaxTimeout specifies the maximum duration a realtime connection + // can remain open (including even if there are ongoing messages). + // + // Once the specified duration expires, the current connection will + // be terminated, until a client reconnect is issued (if the client is still active). + // + // Modifying the value after the connection has been established has no effect. + // + // Defaults to 30 minutes. + MaxTimeout time.Duration } type RealtimeMessageEvent struct {