Skip to content

Commit

Permalink
Resolved race condition issue caused by json.Unmarshal
Browse files Browse the repository at this point in the history
  • Loading branch information
ktsivkov committed Mar 21, 2024
1 parent 1c34ff2 commit 8087bf2
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 22 deletions.
8 changes: 4 additions & 4 deletions caches.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ func (c *Caches) ease(db *gorm.DB, identifier string) {
return
}

q := Query[any]{
Dest: db.Statement.Dest,
RowsAffected: db.Statement.RowsAffected,
q := &Query[any]{
Dest: res.db.Statement.Dest,
RowsAffected: res.db.Statement.RowsAffected,
}
q.replaceOn(res.db)
q.replaceOn(db)
}

func (c *Caches) checkCache(db *gorm.DB, identifier string) bool {
Expand Down
20 changes: 10 additions & 10 deletions easer.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
package caches

import "sync"
import (
"sync"
)

func ease(t task, queue *sync.Map) task {
eq := &eased{
task: t,
wg: &sync.WaitGroup{},
}
eq.wg.Add(1)
defer eq.wg.Done()

runner, ok := queue.LoadOrStore(t.GetId(), eq)
et := runner.(*eased)
if ok {
et := runner.(*eased)
et.wg.Wait()

// If this request is the first of its kind, we execute the Run
if !ok {
et.task.Run()

queue.Delete(et.task.GetId())
et.wg.Done()
return et.task
}

et.wg.Wait()
return et.task
eq.task.Run()
return eq.task
}

type eased struct {
Expand Down
8 changes: 0 additions & 8 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,24 @@ package caches

import (
"encoding/json"
"sync"

"gorm.io/gorm"
)

type Query[T any] struct {
Dest T
RowsAffected int64
mu sync.RWMutex
}

func (q *Query[T]) Marshal() ([]byte, error) {
q.mu.RLock()
defer q.mu.RUnlock()
return json.Marshal(q)
}

func (q *Query[T]) Unmarshal(bytes []byte) error {
q.mu.Lock()
defer q.mu.Unlock()
return json.Unmarshal(bytes, q)
}

func (q *Query[T]) replaceOn(db *gorm.DB) {
q.mu.Lock()
defer q.mu.Unlock()
SetPointedValue(db.Statement.Dest, q.Dest)
SetPointedValue(&db.Statement.RowsAffected, &q.RowsAffected)
}

0 comments on commit 8087bf2

Please sign in to comment.