Skip to content

Commit 160e58e

Browse files
author
Antoine Huret
authored
introduce write sync mechanism to prevent concurrency among simultaneous requests (#62)
1 parent 1bf0d9a commit 160e58e

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func main() {
4848
Password: "admin_password",
4949
Database: "database_name",
5050
URL: "http://localhost:8069",
51+
SyncWriteRequests: true, // prevent concurrency issues in case of simultaneous write requests
5152
})
5253
if err != nil {
5354
log.Fatal(err)

odoo.go

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"errors"
88
"fmt"
99
"log"
10+
"sync"
1011

1112
"github.com/kolo/xmlrpc"
1213
)
@@ -21,10 +22,11 @@ var (
2122

2223
// ClientConfig is the configuration to create a new *Client by givin connection infomations.
2324
type ClientConfig struct {
24-
Database string
25-
Admin string
26-
Password string
27-
URL string
25+
Database string
26+
Admin string
27+
Password string
28+
URL string
29+
SyncWriteRequests bool
2830
}
2931

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

3739
// Client provides high and low level functions to interact with odoo
3840
type Client struct {
39-
common *xmlrpc.Client
40-
object *xmlrpc.Client
41-
cfg *ClientConfig
42-
uid int64
43-
auth bool
41+
common *xmlrpc.Client
42+
object *xmlrpc.Client
43+
cfg *ClientConfig
44+
uid int64
45+
auth bool
46+
syncWriteRequests bool
47+
writeSyncer *sync.Mutex
4448
}
4549

4650
// NewClient creates a new *Client.
@@ -54,6 +58,9 @@ func NewClient(cfg *ClientConfig) (*Client, error) {
5458
object: &xmlrpc.Client{},
5559
auth: false,
5660
}
61+
if c.cfg.SyncWriteRequests {
62+
c.writeSyncer = &sync.Mutex{}
63+
}
5764
if err := c.authenticate(); err != nil {
5865
return nil, err
5966
}
@@ -353,6 +360,11 @@ func (c *Client) ExecuteKw(method, model string, args []interface{}, options *Op
353360
if err := c.checkForAuthentication(); err != nil {
354361
return nil, err
355362
}
363+
if c.cfg.SyncWriteRequests && isWriteMethod(method) {
364+
c.writeSyncer.Lock()
365+
defer c.writeSyncer.Unlock()
366+
}
367+
356368
resp, err := c.objectCall("execute_kw", []interface{}{c.cfg.Database, c.uid, c.cfg.Password, model, method, args, options})
357369
if err != nil {
358370
return nil, err
@@ -449,3 +461,12 @@ func argsFromCriteria(c *Criteria) []interface{} {
449461
}
450462
return []interface{}{}
451463
}
464+
465+
func isWriteMethod(method string) bool {
466+
switch method {
467+
case "create", "write", "unlink":
468+
return true
469+
default:
470+
return false
471+
}
472+
}

0 commit comments

Comments
 (0)