Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for dynamic partitioning config #286

Merged
merged 1 commit into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions channel_config.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package stream_chat

import (
"strconv"
"time"
)

// ChannelConfig is the configuration for a channel.
type ChannelConfig struct {
Name string `json:"name"`
Expand Down Expand Up @@ -34,6 +39,47 @@ type ChannelConfig struct {
BlockList string `json:"blocklist"`
BlockListBehavior modBehaviour `json:"blocklist_behavior"`
AutomodThresholds *Thresholds `json:"automod_thresholds"`

// Dynamic Partitioning
PartitionSize int `json:"partition_size,omitempty"`
PartitionTTL *DurationString `json:"partition_ttl,omitempty"`
}

// DurationString is a duration that's encoded to as a string in JSON.
type DurationString time.Duration

// NewDurationString creates a pointer to a DurationString.
func NewDurationString(d time.Duration) *DurationString {
duration := DurationString(d)
return &duration
}

// MarshalJSON encodes the duration as a string such as "2h30m".
func (d DurationString) MarshalJSON() ([]byte, error) {
if d == 0 {
return []byte("null"), nil
}
return []byte(`"` + time.Duration(d).String() + `"`), nil
}

// String returns the duration as a string such as "2h30m".
func (d DurationString) String() string {
return time.Duration(d).String()
}

// UnmarshalJSON decodes a duration from a string formatted as
// [time.Duration.String()](https://golang.org/pkg/time/#Duration.String)
func (d *DurationString) UnmarshalJSON(b []byte) error {
s, err := strconv.Unquote(string(b))
if err != nil {
return err
}
dur, err := time.ParseDuration(s)
if err != nil {
return err
}
*d = DurationString(dur)
return nil
}

type LabelThresholds struct {
Expand Down
86 changes: 86 additions & 0 deletions channel_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package stream_chat

import (
"encoding/json"
"testing"
"time"
)

func TestDuration_MarshalJSON(t *testing.T) {
tests := []struct {
name string
input DurationString
want string
}{
{
name: "Zero",
input: DurationString(0),
want: `null`,
},
{
name: "Hours",
input: DurationString(24 * time.Hour),
want: `"24h0m0s"`,
},
{
name: "Mixed",
input: DurationString(24*time.Hour + 30*time.Minute + 15*time.Second),
want: `"24h30m15s"`,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.input.MarshalJSON()
if err != nil {
t.Fatal(err)
}
if string(got) != tt.want {
t.Errorf("Duration.MarshalJSON() = %q, want %q", string(got), tt.want)
}
})
}
}

func TestDuration_UnmarshalJSON(t *testing.T) {
tests := []struct {
name string
input string
want DurationString
wantErr bool
}{
{
name: "Hours",
input: `"4h"`,
want: DurationString(4 * time.Hour),
},
{
name: "Mixed",
input: `"2h30m"`,
want: DurationString(2*time.Hour + 30*time.Minute),
},
{
name: "Full",
input: `"6h0m0s"`,
want: DurationString(6 * time.Hour),
},
{
name: "Invalid",
input: "daily",
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var got DurationString
err := json.Unmarshal([]byte(tt.input), &got)
if (err != nil) != tt.wantErr {
t.Fatalf("Error = %q, want error: %t", err, tt.wantErr)
}
if got.String() != tt.want.String() {
t.Errorf("Duration.UnmarshalJSON() = %q, want %q", got, tt.want)
}
})
}
}
Loading