Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
f532e0f2
Commit
f532e0f2
authored
Jul 17, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
9605b703
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
97 additions
and
55 deletions
+97
-55
wcfs/zodb.go
wcfs/zodb.go
+97
-55
No files found.
wcfs/zodb.go
View file @
f532e0f2
...
...
@@ -86,12 +86,6 @@ type Object interface {
PInvalidate
()
}
// XXX
type
Stateful
interface
{
// XXX
DropState
()
}
// PyObject is the interface that every in-RAM object representing Python ZODB object implements.
type
PyObject
interface
{
Object
...
...
@@ -99,21 +93,21 @@ type PyObject interface {
PyClass
()
pickle
.
Class
// python class of this object
// PyState() interface{} // object state. python passes this to pyclass.__new__().__setstate__()
PyStateful
// XXX want to hide from PyObject. Rationale: we do not want e.g. PySetState to
// be available to user who holds PyObject interface: it is confusing to have
// both PActivate and PySetState at the same time.
// PyStateful
}
// XXX
type
PyStateful
interface
{
Stateful
// PySetState should set Python state of the in-RAM object.
// Analog of __setstate__() in Python.
PySetState
(
pystate
interface
{})
error
// ObjectState describe state of in-RAM object.
type
ObjectState
int
// PyGetState should return Python state of in-RAM object.
// Analog of __getstate__() in Python.
//PyGetState() interface{} XXX
}
const
(
GHOST
ObjectState
=
-
1
UPTODATE
=
0
CHANGED
=
1
// no STICKY - we pin objects in RAM with PActivate
)
// object is common base for in-RAM implementations of ZODB objects.
type
object
struct
{
...
...
@@ -121,6 +115,8 @@ type object struct {
oid
zodb
.
Oid
serial
zodb
.
Tid
mu
sync
.
Mutex
state
ObjectState
refcnt
int32
}
...
...
@@ -131,17 +127,50 @@ func (obj *object) PSerial() zodb.Tid { return obj.serial }
// pyObject is common base for in-RAM implementations of ZODB Python objects.
type
pyObject
struct
{
object
pyclass
pickle
.
Class
pyclass
pickle
.
Class
// pystate interface{}
// protected by object.mu
instance
PyStateful
loaderr
error
// if there was error at state loading
ready
chan
struct
{}
// activation complete
loaded
*
loaded
// loaderr error // if there was error at state loading
// ready chan struct{} // activation complete
}
func
(
pyobj
*
pyObject
)
PyClass
()
pickle
.
Class
{
return
pyobj
.
pyclass
}
//func (pyobj *pyObject) PyState() interface{} { return pyobj.pystate }
// loaded indicates object's load state/result.
//
// when !ready the loading is in progress.
// when ready the loading has been completed.
type
loaded
struct
{
ready
chan
struct
{}
// closed when loading finishes
// error from the load.
// if there was no error loaded data goes to object state.
err
error
}
// XXX
type
Stateful
interface
{
// DropState should discard in-RAM object state.
DropState
()
}
// PyStateful is the interface describing in-RAM object whose data state can be
// exchanged as Python data.
type
PyStateful
interface
{
Stateful
// PySetState should set state of the in-RAM object from Python data.
// Analog of __setstate__() in Python.
PySetState
(
pystate
interface
{})
error
// PyGetState should return state of the in-RAM object as Python data.
// Analog of __getstate__() in Python.
//PyGetState() interface{} XXX
}
// Connection represents a view of ZODB database.
//
...
...
@@ -357,7 +386,7 @@ func registerClass(classPath string, classNew func(*pyObject)PyObject) {
// newGhost creates new ghost object corresponding to pyclass and oid.
func
(
conn
*
Connection
)
newGhost
(
pyclass
pickle
.
Class
,
oid
zodb
.
Oid
)
PyObject
{
pyobj
:=
&
pyObject
{
object
:
object
{
jar
:
conn
,
oid
:
oid
,
serial
:
0
},
object
:
object
{
jar
:
conn
,
oid
:
oid
,
serial
:
0
,
state
:
GHOST
},
pyclass
:
pyclass
,
}
...
...
@@ -392,22 +421,16 @@ func (d *dummyPyInstance) PySetState(pystate interface{}) error {
// ----------------------------------------
/*
func (obj *object) PActivate(ctx context.Context) error {
// XXX
}
func (obj *object) PDeactivate() {
// XXX
}
// PInvalidate
*/
// object's activate & friends that only manage base activation state, without actually loading data.
// object's pactivate & friends that only manage base activation state, without actually loading data.
// XXX -> incref ?
func
(
obj
*
object
)
pactivate
()
(
load
bool
)
{
// activate increments object reference counter.
//
// it returns whether object data needs to be loaded.
// must be called with .mu held.
func
(
obj
*
object
)
activate
()
(
load
bool
)
{
obj
.
refcnt
++
return
(
obj
.
refcnt
==
1
&&
obj
.
state
==
GHOST
)
/*
nuse := atomic.AddInt32(&obj.refcnt, +1)
if nuse == 1 {
// we become responsible for loading object's data.
...
...
@@ -415,21 +438,28 @@ func (obj *object) pactivate() (load bool) {
return true
}
return false
*/
}
// XXX -> decref ?
func
(
obj
*
object
)
pdeactivate
()
(
drop
bool
)
{
nuse
:=
atomic
.
AddInt32
(
&
obj
.
refcnt
,
-
1
)
if
nuse
<
0
{
panic
(
"pdeactivate: nuse < 0"
)
// deactivate decrements object reference counter.
//
// it returns whether object data needs to be discarded.
// must be called with .mu held.
func
(
obj
*
object
)
deactivate
()
(
drop
bool
)
{
//nuse := atomic.AddInt32(&obj.refcnt, -1)
obj
.
refcnt
--
if
obj
.
refcnt
<
0
{
panic
(
"deactivate: refcnt < 0"
)
}
if
nuse
>
0
{
if
obj
.
refcnt
>
0
{
return
// users still left
}
// no users left. Let's see whether we should transition this object to ghost.
// TODO state=modified -> don't drop.
drop
=
true
if
obj
.
state
>=
CHANGED
{
drop
=
false
}
// XXX -> pyObject?
if
drop
{
...
...
@@ -440,7 +470,7 @@ func (obj *object) pdeactivate() (drop bool) {
if
drop
{
obj
.
serial
=
0
//obj.ins
ance.DropState()
obj
.
inst
ance
.
DropState
()
}
return
drop
...
...
@@ -449,26 +479,35 @@ func (obj *object) pdeactivate() (drop bool) {
// PActivate implements Object.
func
(
pyobj
*
pyObject
)
PActivate
(
ctx
context
.
Context
)
(
err
error
)
{
load
:=
pyobj
.
object
.
pactivate
()
pyobj
.
mu
.
Lock
()
doload
:=
pyobj
.
activate
()
defer
func
()
{
if
err
!=
nil
{
// no need to check for drop - the state is already
// dropped - we just need to decref here.
pyobj
.
object
.
pdeactivate
()
// XXX locking?
pyobj
.
deactivate
()
}
}()
if
!
load
{
if
!
doload
{
loading
:=
pyobj
.
loading
pyobj
.
mu
.
Unlock
()
// someone else is already activated/activating the object.
// wait for its loading to complete and we are done.
select
{
case
<-
ctx
.
Done
()
:
return
ctx
.
Err
()
// XXX err ctx
case
<-
pyobj
.
ready
:
return
pyobj
.
loaderr
// XXX err ctx?
return
ctx
.
Err
()
// XXX err ctx
case
<-
loading
.
ready
:
return
loading
.
err
// XXX err ctx?
}
}
// we become responsible for loading the object
loading
:=
&
loading
{
ready
:
make
(
chan
struct
{})}
pyobj
.
loading
=
loading
// XXX assert before it was = nil ?
pyobj
.
mu
.
Unlock
()
pyclass
,
pystate
,
serial
,
err
:=
pyobj
.
jar
.
loadpy
(
ctx
,
pyobj
.
oid
)
if
err
==
nil
&&
pyclass
!=
pyobj
.
pyclass
{
// complain pyclass changed
...
...
@@ -477,6 +516,8 @@ func (pyobj *pyObject) PActivate(ctx context.Context) (err error) {
pystate
=
nil
}
pyobj
.
mu
.
Lock
()
pyobj
.
serial
=
serial
// pyobj.pystate = pystate
...
...
@@ -487,16 +528,17 @@ func (pyobj *pyObject) PActivate(ctx context.Context) (err error) {
pyobj
.
instance
.
DropState
()
}
pyobj
.
loaderr
=
err
// XXX unlock
close
(
pyobj
.
ready
)
loading
.
err
=
err
close
(
loading
.
ready
)
return
err
// XXX err ctx
}
// PDeactivate implements Object.
func
(
pyobj
*
pyObject
)
PDeactivate
()
{
drop
:=
pyobj
.
object
.
pdeactivate
()
drop
:=
pyobj
.
pdeactivate
()
if
!
drop
{
return
}
...
...
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