Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
442e0e43
Commit
442e0e43
authored
Jun 07, 2018
by
Torkel Ödegaard
Committed by
bergquist
Jun 15, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactoring: transaction manager PR #12203
parent
6775a82c
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
120 additions
and
122 deletions
+120
-122
pkg/bus/bus.go
+9
-15
pkg/models/transaction.go
+7
-0
pkg/services/sqlstore/session.go
+0
-52
pkg/services/sqlstore/sqlstore.go
+4
-54
pkg/services/sqlstore/transactions.go
+100
-0
pkg/services/sqlstore/user.go
+0
-1
No files found.
pkg/bus/bus.go
View file @
442e0e43
...
...
@@ -12,8 +12,8 @@ type Msg interface{}
var
ErrHandlerNotFound
=
errors
.
New
(
"handler not found"
)
type
Transaction
Wrapp
er
interface
{
Wrap
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
)
error
type
Transaction
Manag
er
interface
{
InTransaction
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
)
error
}
type
Bus
interface
{
...
...
@@ -35,19 +35,18 @@ type Bus interface {
// SetTransactionManager allows the user to replace the internal
// noop TransactionManager that is responsible for manageing
// transactions in `InTransaction`
SetTransactionManager
(
tm
Transaction
Wrapp
er
)
SetTransactionManager
(
tm
Transaction
Manag
er
)
}
func
(
b
*
InProcBus
)
InTransaction
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
)
error
{
return
b
.
t
ransactionWrapper
.
Wrap
(
ctx
,
fn
)
return
b
.
t
xMng
.
InTransaction
(
ctx
,
fn
)
}
type
InProcBus
struct
{
handlers
map
[
string
]
HandlerFunc
listeners
map
[
string
][]
HandlerFunc
wildcardListeners
[]
HandlerFunc
transactionWrapper
TransactionWrapper
txMng
TransactionManager
}
// temp stuff, not sure how to handle bus instance, and init yet
...
...
@@ -58,8 +57,7 @@ func New() Bus {
bus
.
handlers
=
make
(
map
[
string
]
HandlerFunc
)
bus
.
listeners
=
make
(
map
[
string
][]
HandlerFunc
)
bus
.
wildcardListeners
=
make
([]
HandlerFunc
,
0
)
bus
.
transactionWrapper
=
&
noopTransactionManager
{}
bus
.
txMng
=
&
noopTransactionManager
{}
return
bus
}
...
...
@@ -69,12 +67,8 @@ func GetBus() Bus {
return
globalBus
}
func
SetTransactionManager
(
tm
TransactionWrapper
)
{
globalBus
.
SetTransactionManager
(
tm
)
}
func
(
b
*
InProcBus
)
SetTransactionManager
(
tm
TransactionWrapper
)
{
b
.
transactionWrapper
=
tm
func
(
b
*
InProcBus
)
SetTransactionManager
(
tm
TransactionManager
)
{
b
.
txMng
=
tm
}
func
(
b
*
InProcBus
)
DispatchCtx
(
ctx
context
.
Context
,
msg
Msg
)
error
{
...
...
@@ -213,6 +207,6 @@ func ClearBusHandlers() {
type
noopTransactionManager
struct
{}
func
(
*
noopTransactionManager
)
Wrap
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
)
error
{
func
(
*
noopTransactionManager
)
InTransaction
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
)
error
{
return
nil
}
pkg/models/transaction.go
0 → 100644
View file @
442e0e43
package
models
import
"context"
type
TransactionManager
interface
{
InTransaction
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
)
error
}
pkg/services/sqlstore/s
hared
.go
→
pkg/services/sqlstore/s
ession
.go
View file @
442e0e43
...
...
@@ -3,12 +3,8 @@ package sqlstore
import
(
"context"
"reflect"
"time"
"github.com/go-xorm/xorm"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
sqlite3
"github.com/mattn/go-sqlite3"
)
type
DBSession
struct
{
...
...
@@ -26,10 +22,6 @@ func newSession() *DBSession {
return
&
DBSession
{
Session
:
x
.
NewSession
()}
}
func
inTransaction
(
callback
dbTransactionFunc
)
error
{
return
inTransactionWithRetry
(
callback
,
0
)
}
func
startSession
(
ctx
context
.
Context
)
*
DBSession
{
value
:=
ctx
.
Value
(
ContextSessionName
)
var
sess
*
DBSession
...
...
@@ -50,50 +42,6 @@ func withDbSession(ctx context.Context, callback dbTransactionFunc) error {
return
callback
(
sess
)
}
func
inTransactionWithRetry
(
callback
dbTransactionFunc
,
retry
int
)
error
{
return
inTransactionWithRetryCtx
(
context
.
Background
(),
callback
,
retry
)
}
func
inTransactionWithRetryCtx
(
ctx
context
.
Context
,
callback
dbTransactionFunc
,
retry
int
)
error
{
var
err
error
sess
:=
startSession
(
ctx
)
defer
sess
.
Close
()
if
err
=
sess
.
Begin
();
err
!=
nil
{
return
err
}
err
=
callback
(
sess
)
// special handling of database locked errors for sqlite, then we can retry 3 times
if
sqlError
,
ok
:=
err
.
(
sqlite3
.
Error
);
ok
&&
retry
<
5
{
if
sqlError
.
Code
==
sqlite3
.
ErrLocked
{
sess
.
Rollback
()
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
10
))
sqlog
.
Info
(
"Database table locked, sleeping then retrying"
,
"retry"
,
retry
)
return
inTransactionWithRetry
(
callback
,
retry
+
1
)
}
}
if
err
!=
nil
{
sess
.
Rollback
()
return
err
}
else
if
err
=
sess
.
Commit
();
err
!=
nil
{
return
err
}
if
len
(
sess
.
events
)
>
0
{
for
_
,
e
:=
range
sess
.
events
{
if
err
=
bus
.
Publish
(
e
);
err
!=
nil
{
log
.
Error
(
3
,
"Failed to publish event after commit"
,
err
)
}
}
}
return
nil
}
func
(
sess
*
DBSession
)
InsertId
(
bean
interface
{})
(
int64
,
error
)
{
table
:=
sess
.
DB
()
.
Mapper
.
Obj2Table
(
getTypeName
(
bean
))
...
...
pkg/services/sqlstore/sqlstore.go
View file @
442e0e43
...
...
@@ -23,11 +23,10 @@ import (
"github.com/go-sql-driver/mysql"
"github.com/go-xorm/xorm"
_
"github.com/lib/pq"
_
"github.com/mattn/go-sqlite3"
sqlite3
"github.com/mattn/go-sqlite3"
_
"github.com/grafana/grafana/pkg/tsdb/mssql"
_
"github.com/lib/pq"
_
"github.com/mattn/go-sqlite3"
)
var
(
...
...
@@ -82,9 +81,7 @@ func (ss *SqlStore) Init() error {
// Init repo instances
annotations
.
SetRepository
(
&
SqlAnnotationRepo
{})
ss
.
Bus
.
SetTransactionManager
(
&
SQLTransactionManager
{
engine
:
ss
.
engine
,
})
ss
.
Bus
.
SetTransactionManager
(
ss
)
// ensure admin user
if
ss
.
skipEnsureAdmin
{
...
...
@@ -94,57 +91,10 @@ func (ss *SqlStore) Init() error {
return
ss
.
ensureAdminUser
()
}
// SQLTransactionManager begin/end transaction
type
SQLTransactionManager
struct
{
engine
*
xorm
.
Engine
}
func
(
stm
*
SQLTransactionManager
)
Wrap
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
)
error
{
return
stm
.
wrapInternal
(
ctx
,
fn
,
0
)
}
func
(
stm
*
SQLTransactionManager
)
wrapInternal
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
,
retry
int
)
error
{
sess
:=
startSession
(
ctx
)
defer
sess
.
Close
()
withValue
:=
context
.
WithValue
(
ctx
,
ContextSessionName
,
sess
)
err
:=
fn
(
withValue
)
// special handling of database locked errors for sqlite, then we can retry 3 times
if
sqlError
,
ok
:=
err
.
(
sqlite3
.
Error
);
ok
&&
retry
<
5
{
if
sqlError
.
Code
==
sqlite3
.
ErrLocked
{
sess
.
Rollback
()
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
10
))
sqlog
.
Info
(
"Database table locked, sleeping then retrying"
,
"retry"
,
retry
)
return
stm
.
wrapInternal
(
ctx
,
fn
,
retry
+
1
)
}
}
if
err
!=
nil
{
sess
.
Rollback
()
return
err
}
if
err
=
sess
.
Commit
();
err
!=
nil
{
return
err
}
if
len
(
sess
.
events
)
>
0
{
for
_
,
e
:=
range
sess
.
events
{
if
err
=
bus
.
Publish
(
e
);
err
!=
nil
{
log
.
Error
(
3
,
"Failed to publish event after commit"
,
err
)
}
}
}
return
nil
}
func
(
ss
*
SqlStore
)
ensureAdminUser
()
error
{
systemUserCountQuery
:=
m
.
GetSystemUserCountStatsQuery
{}
err
:=
bu
s
.
InTransaction
(
context
.
Background
(),
func
(
ctx
context
.
Context
)
error
{
err
:=
s
s
.
InTransaction
(
context
.
Background
(),
func
(
ctx
context
.
Context
)
error
{
err
:=
bus
.
DispatchCtx
(
ctx
,
&
systemUserCountQuery
)
if
err
!=
nil
{
...
...
pkg/services/sqlstore/transactions.go
0 → 100644
View file @
442e0e43
package
sqlstore
import
(
"context"
"time"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/log"
sqlite3
"github.com/mattn/go-sqlite3"
)
func
(
ss
*
SqlStore
)
InTransaction
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
)
error
{
return
ss
.
inTransactionWithRetry
(
ctx
,
fn
,
0
)
}
func
(
ss
*
SqlStore
)
inTransactionWithRetry
(
ctx
context
.
Context
,
fn
func
(
ctx
context
.
Context
)
error
,
retry
int
)
error
{
sess
:=
startSession
(
ctx
)
defer
sess
.
Close
()
withValue
:=
context
.
WithValue
(
ctx
,
ContextSessionName
,
sess
)
err
:=
fn
(
withValue
)
// special handling of database locked errors for sqlite, then we can retry 3 times
if
sqlError
,
ok
:=
err
.
(
sqlite3
.
Error
);
ok
&&
retry
<
5
{
if
sqlError
.
Code
==
sqlite3
.
ErrLocked
{
sess
.
Rollback
()
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
10
))
ss
.
log
.
Info
(
"Database table locked, sleeping then retrying"
,
"retry"
,
retry
)
return
ss
.
inTransactionWithRetry
(
ctx
,
fn
,
retry
+
1
)
}
}
if
err
!=
nil
{
sess
.
Rollback
()
return
err
}
if
err
=
sess
.
Commit
();
err
!=
nil
{
return
err
}
if
len
(
sess
.
events
)
>
0
{
for
_
,
e
:=
range
sess
.
events
{
if
err
=
bus
.
Publish
(
e
);
err
!=
nil
{
ss
.
log
.
Error
(
"Failed to publish event after commit"
,
err
)
}
}
}
return
nil
}
func
inTransactionWithRetry
(
callback
dbTransactionFunc
,
retry
int
)
error
{
return
inTransactionWithRetryCtx
(
context
.
Background
(),
callback
,
retry
)
}
func
inTransactionWithRetryCtx
(
ctx
context
.
Context
,
callback
dbTransactionFunc
,
retry
int
)
error
{
var
err
error
sess
:=
startSession
(
ctx
)
defer
sess
.
Close
()
if
err
=
sess
.
Begin
();
err
!=
nil
{
return
err
}
err
=
callback
(
sess
)
// special handling of database locked errors for sqlite, then we can retry 3 times
if
sqlError
,
ok
:=
err
.
(
sqlite3
.
Error
);
ok
&&
retry
<
5
{
if
sqlError
.
Code
==
sqlite3
.
ErrLocked
{
sess
.
Rollback
()
time
.
Sleep
(
time
.
Millisecond
*
time
.
Duration
(
10
))
sqlog
.
Info
(
"Database table locked, sleeping then retrying"
,
"retry"
,
retry
)
return
inTransactionWithRetry
(
callback
,
retry
+
1
)
}
}
if
err
!=
nil
{
sess
.
Rollback
()
return
err
}
else
if
err
=
sess
.
Commit
();
err
!=
nil
{
return
err
}
if
len
(
sess
.
events
)
>
0
{
for
_
,
e
:=
range
sess
.
events
{
if
err
=
bus
.
Publish
(
e
);
err
!=
nil
{
log
.
Error
(
3
,
"Failed to publish event after commit"
,
err
)
}
}
}
return
nil
}
func
inTransaction
(
callback
dbTransactionFunc
)
error
{
return
inTransactionWithRetry
(
callback
,
0
)
}
pkg/services/sqlstore/user.go
View file @
442e0e43
...
...
@@ -31,7 +31,6 @@ func init() {
bus
.
AddHandler
(
"sql"
,
DeleteUser
)
bus
.
AddHandler
(
"sql"
,
UpdateUserPermissions
)
bus
.
AddHandler
(
"sql"
,
SetUserHelpFlag
)
bus
.
AddCtxHandler
(
"sql"
,
CreateUserCtx
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment