Support passing TTL when setting transient data from clients.

This commit is contained in:
Joachim Bauch 2023-10-12 10:33:01 +02:00
parent 1ace748432
commit b006903a56
No known key found for this signature in database
GPG key ID: 77C1D22D53E15F02
6 changed files with 28 additions and 11 deletions

View file

@ -28,6 +28,7 @@ import (
"net/url"
"sort"
"strings"
"time"
"github.com/golang-jwt/jwt/v4"
)
@ -847,6 +848,7 @@ type TransientDataClientMessage struct {
Key string `json:"key,omitempty"`
Value *json.RawMessage `json:"value,omitempty"`
TTL time.Duration `json:"ttl,omitempty"`
}
func (m *TransientDataClientMessage) CheckValid() error {

View file

@ -817,14 +817,17 @@ Message format (Client -> Server):
"transient": {
"type": "set",
"key": "sample-key",
"value": "any-json-object"
"value": "any-json-object",
"ttl": "optional-ttl"
}
}
- The `key` must be a string.
- The `value` can be of any type (i.e. string, number, array, object, etc.).
- The `ttl` is the time to live in nanoseconds. The value will be removed after
that time (if it is still present).
- Requests to set a value that is already present for the key are silently
ignored.
ignored. Any TTL value will be updated / removed.
Message format (Server -> Client):

4
hub.go
View file

@ -1965,9 +1965,9 @@ func (h *Hub) processTransientMsg(client *Client, message *ClientMessage) {
}
if msg.Value == nil {
room.SetTransientData(msg.Key, nil)
room.SetTransientDataTTL(msg.Key, nil, msg.TTL)
} else {
room.SetTransientData(msg.Key, *msg.Value)
room.SetTransientDataTTL(msg.Key, *msg.Value, msg.TTL)
}
case "remove":
if !isAllowedToUpdateTransientData(session) {

View file

@ -1059,6 +1059,10 @@ func (r *Room) SetTransientData(key string, value interface{}) {
r.transientData.Set(key, value)
}
func (r *Room) SetTransientDataTTL(key string, value interface{}, ttl time.Duration) {
r.transientData.SetTTL(key, value, ttl)
}
func (r *Room) RemoveTransientData(key string) {
r.transientData.Remove(key)
}

View file

@ -578,7 +578,7 @@ func (c *TestClient) SendInternalRemoveSession(msg *RemoveSessionInternalClientM
return c.WriteJSON(message)
}
func (c *TestClient) SetTransientData(key string, value interface{}) error {
func (c *TestClient) SetTransientData(key string, value interface{}, ttl time.Duration) error {
payload, err := json.Marshal(value)
if err != nil {
c.t.Fatal(err)
@ -591,6 +591,7 @@ func (c *TestClient) SetTransientData(key string, value interface{}) error {
Type: "set",
Key: key,
Value: (*json.RawMessage)(&payload),
TTL: ttl,
},
}
return c.WriteJSON(message)

View file

@ -148,7 +148,7 @@ func Test_TransientMessages(t *testing.T) {
t.Fatal(err)
}
if err := client1.SetTransientData("foo", "bar"); err != nil {
if err := client1.SetTransientData("foo", "bar", 0); err != nil {
t.Fatal(err)
}
if msg, err := client1.RunUntilMessage(ctx); err != nil {
@ -202,7 +202,7 @@ func Test_TransientMessages(t *testing.T) {
// Client 2 may not modify transient data.
session2.SetPermissions([]Permission{})
if err := client2.SetTransientData("foo", "bar"); err != nil {
if err := client2.SetTransientData("foo", "bar", 0); err != nil {
t.Fatal(err)
}
if msg, err := client2.RunUntilMessage(ctx); err != nil {
@ -213,7 +213,7 @@ func Test_TransientMessages(t *testing.T) {
}
}
if err := client1.SetTransientData("foo", "bar"); err != nil {
if err := client1.SetTransientData("foo", "bar", 0); err != nil {
t.Fatal(err)
}
@ -244,7 +244,7 @@ func Test_TransientMessages(t *testing.T) {
}
// Setting the same value is ignored by the server.
if err := client1.SetTransientData("foo", "bar"); err != nil {
if err := client1.SetTransientData("foo", "bar", 0); err != nil {
t.Fatal(err)
}
ctx2, cancel2 := context.WithTimeout(context.Background(), 100*time.Millisecond)
@ -261,7 +261,7 @@ func Test_TransientMessages(t *testing.T) {
data := map[string]interface{}{
"hello": "world",
}
if err := client1.SetTransientData("foo", data); err != nil {
if err := client1.SetTransientData("foo", data, 0); err != nil {
t.Fatal(err)
}
@ -314,7 +314,7 @@ func Test_TransientMessages(t *testing.T) {
t.Errorf("Expected no payload, got %+v", msg)
}
if err := client1.SetTransientData("abc", data); err != nil {
if err := client1.SetTransientData("abc", data, 10*time.Millisecond); err != nil {
t.Fatal(err)
}
@ -355,4 +355,11 @@ func Test_TransientMessages(t *testing.T) {
}); err != nil {
t.Fatal(err)
}
time.Sleep(10 * time.Millisecond)
if msg, err = client3.RunUntilMessage(ctx); err != nil {
t.Fatal(err)
} else if err := checkMessageTransientRemove(msg, "abc", data); err != nil {
t.Fatal(err)
}
}