Skip to content

Commit a5ef5a2

Browse files
authored
session: Remove incorrect UTC conversion, alter app_state/user_state to text (#623)
1 parent 76cab5d commit a5ef5a2

File tree

9 files changed

+157
-44
lines changed

9 files changed

+157
-44
lines changed

docs/mkdocs/en/session.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ CREATE TABLE app_states (
595595
id BIGSERIAL PRIMARY KEY,
596596
app_name VARCHAR(255) NOT NULL,
597597
key VARCHAR(255) NOT NULL,
598-
value BYTEA NOT NULL,
598+
value TEXT DEFAULT NULL,
599599
created_at TIMESTAMP NOT NULL,
600600
updated_at TIMESTAMP NOT NULL,
601601
expires_at TIMESTAMP,
@@ -609,7 +609,7 @@ CREATE TABLE user_states (
609609
app_name VARCHAR(255) NOT NULL,
610610
user_id VARCHAR(255) NOT NULL,
611611
key VARCHAR(255) NOT NULL,
612-
value BYTEA NOT NULL,
612+
value TEXT DEFAULT NULL,
613613
created_at TIMESTAMP NOT NULL,
614614
updated_at TIMESTAMP NOT NULL,
615615
expires_at TIMESTAMP,

docs/mkdocs/zh/session.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ CREATE TABLE app_states (
601601
id BIGSERIAL PRIMARY KEY,
602602
app_name VARCHAR(255) NOT NULL,
603603
key VARCHAR(255) NOT NULL,
604-
value BYTEA NOT NULL,
604+
value TEXT DEFAULT NULL,
605605
created_at TIMESTAMP NOT NULL,
606606
updated_at TIMESTAMP NOT NULL,
607607
expires_at TIMESTAMP,
@@ -615,7 +615,7 @@ CREATE TABLE user_states (
615615
app_name VARCHAR(255) NOT NULL,
616616
user_id VARCHAR(255) NOT NULL,
617617
key VARCHAR(255) NOT NULL,
618-
value BYTEA NOT NULL,
618+
value TEXT DEFAULT NULL,
619619
created_at TIMESTAMP NOT NULL,
620620
updated_at TIMESTAMP NOT NULL,
621621
expires_at TIMESTAMP,

examples/runner/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func (c *multiTurnChat) setup(_ context.Context) error {
145145
postgres.WithUser(pgUser),
146146
postgres.WithPassword(pgPassword),
147147
postgres.WithDatabase(pgDatabase),
148-
postgres.WithTablePrefix("tRPC"),
148+
postgres.WithTablePrefix("trpc_"),
149149
)
150150
if err != nil {
151151
return fmt.Errorf("failed to create postgres session service: %w", err)

session/postgres/init.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ const (
8181
id BIGSERIAL PRIMARY KEY,
8282
app_name VARCHAR(255) NOT NULL,
8383
key VARCHAR(255) NOT NULL,
84-
value BYTEA DEFAULT NULL,
84+
value TEXT DEFAULT NULL,
8585
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8686
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8787
expires_at TIMESTAMP DEFAULT NULL,
@@ -94,7 +94,7 @@ const (
9494
app_name VARCHAR(255) NOT NULL,
9595
user_id VARCHAR(255) NOT NULL,
9696
key VARCHAR(255) NOT NULL,
97-
value BYTEA DEFAULT NULL,
97+
value TEXT DEFAULT NULL,
9898
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
9999
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
100100
expires_at TIMESTAMP DEFAULT NULL,
@@ -232,7 +232,7 @@ var expectedSchema = map[string]struct {
232232
{"id", "bigint", false},
233233
{"app_name", "character varying", false},
234234
{"key", "character varying", false},
235-
{"value", "bytea", true},
235+
{"value", "text", true},
236236
{"created_at", "timestamp without time zone", false},
237237
{"updated_at", "timestamp without time zone", false},
238238
{"expires_at", "timestamp without time zone", true},
@@ -249,7 +249,7 @@ var expectedSchema = map[string]struct {
249249
{"app_name", "character varying", false},
250250
{"user_id", "character varying", false},
251251
{"key", "character varying", false},
252-
{"value", "bytea", true},
252+
{"value", "text", true},
253253
{"created_at", "timestamp without time zone", false},
254254
{"updated_at", "timestamp without time zone", false},
255255
{"expires_at", "timestamp without time zone", true},

session/postgres/schema.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ CREATE TABLE IF NOT EXISTS app_states (
8282
id BIGSERIAL PRIMARY KEY,
8383
app_name VARCHAR(255) NOT NULL,
8484
key VARCHAR(255) NOT NULL,
85-
value BYTEA DEFAULT NULL,
85+
value TEXT DEFAULT NULL,
8686
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8787
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8888
expires_at TIMESTAMP DEFAULT NULL,
@@ -106,7 +106,7 @@ CREATE TABLE IF NOT EXISTS user_states (
106106
app_name VARCHAR(255) NOT NULL,
107107
user_id VARCHAR(255) NOT NULL,
108108
key VARCHAR(255) NOT NULL,
109-
value BYTEA DEFAULT NULL,
109+
value TEXT DEFAULT NULL,
110110
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
111111
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
112112
expires_at TIMESTAMP DEFAULT NULL,

session/postgres/service.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ func (s *Service) CreateSession(
253253
key.SessionID = uuid.New().String()
254254
}
255255

256-
now := time.Now().UTC()
256+
now := time.Now()
257257
sessState := &SessionState{
258258
ID: key.SessionID,
259259
State: make(session.StateMap),
@@ -405,7 +405,7 @@ func (s *Service) UpdateAppState(ctx context.Context, appName string, state sess
405405
return session.ErrAppNameRequired
406406
}
407407

408-
now := time.Now().UTC()
408+
now := time.Now()
409409
var expiresAt *time.Time
410410
if s.appStateTTL > 0 {
411411
t := now.Add(s.appStateTTL)
@@ -453,7 +453,7 @@ func (s *Service) ListAppStates(ctx context.Context, appName string) (session.St
453453
WHERE app_name = $1
454454
AND (expires_at IS NULL OR expires_at > $2)
455455
AND deleted_at IS NULL`, s.tableAppStates),
456-
appName, time.Now().UTC())
456+
appName, time.Now())
457457

458458
if err != nil {
459459
return nil, fmt.Errorf("postgres session service list app states failed: %w", err)
@@ -476,7 +476,7 @@ func (s *Service) DeleteAppState(ctx context.Context, appName string, key string
476476
_, err = s.pgClient.ExecContext(ctx,
477477
fmt.Sprintf(`UPDATE %s SET deleted_at = $1
478478
WHERE app_name = $2 AND key = $3 AND deleted_at IS NULL`, s.tableAppStates),
479-
time.Now().UTC(), appName, key)
479+
time.Now(), appName, key)
480480
} else {
481481
// Hard delete: permanently remove record
482482
_, err = s.pgClient.ExecContext(ctx,
@@ -497,7 +497,7 @@ func (s *Service) UpdateUserState(ctx context.Context, userKey session.UserKey,
497497
return err
498498
}
499499

500-
now := time.Now().UTC()
500+
now := time.Now()
501501
var expiresAt *time.Time
502502
if s.userStateTTL > 0 {
503503
t := now.Add(s.userStateTTL)
@@ -545,7 +545,7 @@ func (s *Service) ListUserStates(ctx context.Context, userKey session.UserKey) (
545545
WHERE app_name = $1 AND user_id = $2
546546
AND (expires_at IS NULL OR expires_at > $3)
547547
AND deleted_at IS NULL`, s.tableUserStates),
548-
userKey.AppName, userKey.UserID, time.Now().UTC())
548+
userKey.AppName, userKey.UserID, time.Now())
549549

550550
if err != nil {
551551
return nil, fmt.Errorf("postgres session service list user states failed: %w", err)
@@ -567,7 +567,7 @@ func (s *Service) DeleteUserState(ctx context.Context, userKey session.UserKey,
567567
_, err = s.pgClient.ExecContext(ctx,
568568
fmt.Sprintf(`UPDATE %s SET deleted_at = $1
569569
WHERE app_name = $2 AND user_id = $3 AND key = $4 AND deleted_at IS NULL`, s.tableUserStates),
570-
time.Now().UTC(), userKey.AppName, userKey.UserID, key)
570+
time.Now(), userKey.AppName, userKey.UserID, key)
571571
} else {
572572
_, err = s.pgClient.ExecContext(ctx,
573573
fmt.Sprintf(`DELETE FROM %s
@@ -664,7 +664,7 @@ func (s *Service) getSession(
664664
WHERE app_name = $1 AND user_id = $2 AND session_id = $3
665665
AND (expires_at IS NULL OR expires_at > $4)
666666
AND deleted_at IS NULL`, s.tableSessionStates)
667-
stateArgs := []interface{}{key.AppName, key.UserID, key.SessionID, time.Now().UTC()}
667+
stateArgs := []interface{}{key.AppName, key.UserID, key.SessionID, time.Now()}
668668

669669
err := s.pgClient.Query(ctx, func(rows *sql.Rows) error {
670670
if rows.Next() {
@@ -708,7 +708,7 @@ func (s *Service) getSession(
708708
// Query events (always filter deleted records)
709709
// Note: limit here only controls how many events to return, not delete from database
710710
events := []event.Event{}
711-
now := time.Now().UTC()
711+
now := time.Now()
712712
var eventQuery string
713713
var eventArgs []interface{}
714714

@@ -761,7 +761,7 @@ func (s *Service) getSession(
761761
WHERE app_name = $1 AND user_id = $2 AND session_id = $3
762762
AND (expires_at IS NULL OR expires_at > $4)
763763
AND deleted_at IS NULL`, s.tableSessionSummaries)
764-
summaryArgs := []interface{}{key.AppName, key.UserID, key.SessionID, time.Now().UTC()}
764+
summaryArgs := []interface{}{key.AppName, key.UserID, key.SessionID, time.Now()}
765765

766766
err = s.pgClient.Query(ctx, func(rows *sql.Rows) error {
767767
for rows.Next() {
@@ -822,7 +822,7 @@ func (s *Service) listSessions(
822822
AND (expires_at IS NULL OR expires_at > $3)
823823
AND deleted_at IS NULL
824824
ORDER BY updated_at DESC`, s.tableSessionStates)
825-
listArgs := []interface{}{key.AppName, key.UserID, time.Now().UTC()}
825+
listArgs := []interface{}{key.AppName, key.UserID, time.Now()}
826826

827827
err = s.pgClient.Query(ctx, func(rows *sql.Rows) error {
828828
for rows.Next() {
@@ -890,7 +890,7 @@ func (s *Service) listSessions(
890890
}
891891

892892
func (s *Service) addEvent(ctx context.Context, key session.Key, event *event.Event) error {
893-
now := time.Now().UTC()
893+
now := time.Now()
894894

895895
// Get current session state (always filter deleted records, but allow expired sessions)
896896
var sessState *SessionState
@@ -1031,7 +1031,7 @@ func (s *Service) enforceEventLimit(ctx context.Context, tx *sql.Tx, key session
10311031
// refreshSessionTTL updates the session's updated_at and expires_at timestamps.
10321032
// This effectively "renews" the session, extending its lifetime by the configured TTL.
10331033
func (s *Service) refreshSessionTTL(ctx context.Context, key session.Key) error {
1034-
now := time.Now().UTC()
1034+
now := time.Now()
10351035
expiresAt := now.Add(s.sessionTTL)
10361036

10371037
_, err := s.pgClient.ExecContext(ctx,
@@ -1051,7 +1051,7 @@ func (s *Service) deleteSessionState(ctx context.Context, key session.Key) error
10511051
err := s.pgClient.Transaction(ctx, func(tx *sql.Tx) error {
10521052
if s.opts.softDelete {
10531053
// Soft delete: set deleted_at timestamp
1054-
now := time.Now().UTC()
1054+
now := time.Now()
10551055

10561056
// Soft delete session state
10571057
_, err := tx.ExecContext(ctx,
@@ -1222,7 +1222,7 @@ func (s *Service) getEventsList(
12221222
LIMIT $6
12231223
) e ON true
12241224
ORDER BY s.session_id`, s.tableSessionEvents)
1225-
args = []interface{}{sessionIDs, sessionKeys[0].AppName, sessionKeys[0].UserID, time.Now().UTC(), afterTime, limit}
1225+
args = []interface{}{sessionIDs, sessionKeys[0].AppName, sessionKeys[0].UserID, time.Now(), afterTime, limit}
12261226
} else {
12271227
// Without limit: simple query with IN clause
12281228
query = fmt.Sprintf(`
@@ -1234,7 +1234,7 @@ func (s *Service) getEventsList(
12341234
AND created_at > $5
12351235
AND deleted_at IS NULL
12361236
ORDER BY session_id, created_at DESC`, s.tableSessionEvents)
1237-
args = []interface{}{sessionKeys[0].AppName, sessionKeys[0].UserID, sessionIDs, time.Now().UTC(), afterTime}
1237+
args = []interface{}{sessionKeys[0].AppName, sessionKeys[0].UserID, sessionIDs, time.Now(), afterTime}
12381238
}
12391239

12401240
// Execute query and group events by session
@@ -1324,7 +1324,7 @@ func (s *Service) getSummariesList(
13241324
summariesMap[sessionID][filterKey] = &sum
13251325
}
13261326
return nil
1327-
}, summaryQuery, sessionKeys[0].AppName, sessionKeys[0].UserID, sessionIDs, time.Now().UTC())
1327+
}, summaryQuery, sessionKeys[0].AppName, sessionKeys[0].UserID, sessionIDs, time.Now())
13281328

13291329
if err != nil {
13301330
return nil, fmt.Errorf("query summaries failed: %w", err)
@@ -1358,7 +1358,7 @@ func (s *Service) cleanupExpiredForUser(ctx context.Context, userKey session.Use
13581358
// If userKey is nil, it cleans up all expired data globally.
13591359
// If userKey is provided, it only cleans up expired data for that specific user.
13601360
func (s *Service) cleanupExpiredData(ctx context.Context, userKey *session.UserKey) {
1361-
now := time.Now().UTC()
1361+
now := time.Now()
13621362

13631363
// Define cleanup tasks: table name, TTL, and whether it's session-scoped
13641364
type cleanupTask struct {

session/postgres/service_edge_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func TestGetSession_RefreshTTL(t *testing.T) {
6060
}
6161
stateBytes, _ := json.Marshal(sessState)
6262
stateRows := sqlmock.NewRows([]string{"state", "created_at", "updated_at"}).
63-
AddRow(stateBytes, time.Now().UTC(), time.Now().UTC())
63+
AddRow(stateBytes, time.Now(), time.Now())
6464

6565
mock.ExpectQuery("SELECT state, created_at, updated_at FROM session_states").
6666
WithArgs("test-app", "test-user", "test-session", sqlmock.AnyArg()).
@@ -232,7 +232,7 @@ func TestAppendEvent_ToExpiredSession(t *testing.T) {
232232
State: session.StateMap{},
233233
}
234234
stateBytes, _ := json.Marshal(sessState)
235-
pastTime := time.Now().UTC().Add(-2 * time.Hour)
235+
pastTime := time.Now().Add(-2 * time.Hour)
236236
stateRows := sqlmock.NewRows([]string{"state", "expires_at"}).
237237
AddRow(stateBytes, pastTime)
238238

0 commit comments

Comments
 (0)