Skip to content

Commit

Permalink
introduce write sync mechanism to prevent concurrency among simultane…
Browse files Browse the repository at this point in the history
…ous requests (#62)
  • Loading branch information
ahuret authored Oct 16, 2024
1 parent 1bf0d9a commit 160e58e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func main() {
Password: "admin_password",
Database: "database_name",
URL: "http://localhost:8069",
SyncWriteRequests: true, // prevent concurrency issues in case of simultaneous write requests
})
if err != nil {
log.Fatal(err)
Expand Down
39 changes: 30 additions & 9 deletions odoo.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"log"
"sync"

"github.com/kolo/xmlrpc"
)
Expand All @@ -21,10 +22,11 @@ var (

// ClientConfig is the configuration to create a new *Client by givin connection infomations.
type ClientConfig struct {
Database string
Admin string
Password string
URL string
Database string
Admin string
Password string
URL string
SyncWriteRequests bool
}

func (c *ClientConfig) valid() bool {
Expand All @@ -36,11 +38,13 @@ func (c *ClientConfig) valid() bool {

// Client provides high and low level functions to interact with odoo
type Client struct {
common *xmlrpc.Client
object *xmlrpc.Client
cfg *ClientConfig
uid int64
auth bool
common *xmlrpc.Client
object *xmlrpc.Client
cfg *ClientConfig
uid int64
auth bool
syncWriteRequests bool
writeSyncer *sync.Mutex
}

// NewClient creates a new *Client.
Expand All @@ -54,6 +58,9 @@ func NewClient(cfg *ClientConfig) (*Client, error) {
object: &xmlrpc.Client{},
auth: false,
}
if c.cfg.SyncWriteRequests {
c.writeSyncer = &sync.Mutex{}
}
if err := c.authenticate(); err != nil {
return nil, err
}
Expand Down Expand Up @@ -353,6 +360,11 @@ func (c *Client) ExecuteKw(method, model string, args []interface{}, options *Op
if err := c.checkForAuthentication(); err != nil {
return nil, err
}
if c.cfg.SyncWriteRequests && isWriteMethod(method) {
c.writeSyncer.Lock()
defer c.writeSyncer.Unlock()
}

resp, err := c.objectCall("execute_kw", []interface{}{c.cfg.Database, c.uid, c.cfg.Password, model, method, args, options})
if err != nil {
return nil, err
Expand Down Expand Up @@ -449,3 +461,12 @@ func argsFromCriteria(c *Criteria) []interface{} {
}
return []interface{}{}
}

func isWriteMethod(method string) bool {
switch method {
case "create", "write", "unlink":
return true
default:
return false
}
}

0 comments on commit 160e58e

Please sign in to comment.