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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
171cdb09
Commit
171cdb09
authored
Jul 13, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
1bbc897a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
51 additions
and
2 deletions
+51
-2
wcfs/zodb.go
wcfs/zodb.go
+51
-2
No files found.
wcfs/zodb.go
View file @
171cdb09
...
...
@@ -42,6 +42,52 @@ type PyObject struct {
type
Connection
struct
{
stor
zodb
.
IStorage
// underlying storage
at
zodb
.
Tid
// current view of database
// {} oid -> pyobj
//
// rationale:
//
// on invalidations: we need to go oid -> pyobj and invalidate it.
// -> Connection need to keep {} oid -> pyobj.
// -> we can use that {} when loading a persistent Ref twice to get to the same object.
//
// however: if Connection keeps strong link to pyobj, just
// pyobj.PDeactivate will not fully release pyobj if there are not
// references to it from other objects:
//
// - deactivate will release pyobj state (ok)
// - but there will be still reference from connection `oid -> pyobj` map to this object.
//
// -> we can solve it by using "weak" pointers in the map.
//
// NOTE we cannot use regular map and arbitrarily manually "gc" entries
// there periodically: since for a pyobj we don't know whether other
// objects are referencing it, we can't just remove pyobj's oid from
// the map - if we do so and there are other live objects that
// reference pyobj, user code can still reach pyobj via those
// references. On the other hand, if another, not yet loaded, object
// also references pyobj and gets loaded, traversing reference from
// that loaded object will load second copy of pyobj, thus breaking 1
// object in db <-> 1 live object invariant:
//
// A → B → C
// ↓ |
// D <--------- - - -> D2 (wrong)
//
// - A activate
// - D activate
// - B activate
// - D gc, A still keeps link on D
// - C activate -> it needs to get to D, but D was removed from objtab
// -> new D2 is wrongly created
//
// that's why we have to depend on Go's GC to know whether there are
// still live references left or not. And that in turn means finalizers
// and thus weak references.
//
// some link on the subject:
// https://groups.google.com/forum/#!topic/golang-nuts/PYWxjT2v6ps
objtab
map
[
zodb
.
Oid
]
WeakRef
}
// Gets loads and decodes object from the database according to its current view.
...
...
@@ -98,12 +144,15 @@ func (conn *Connection) newGhost(pyclass pickle.Class, oid zodb.Oid) interface{}
return
&
pyobj
}
// XXX pyobj.PInvalidate() = deactivate without checking if state != modified
// PDeactivates transforms object to ghost state.
//
// In ghost state object data is dropped and only oid/pyclass information is left in RAM.
//
// XXX if state=modified PDeactivate must be noop.
func
(
pyobj
*
PyObject
)
PDeactivate
()
{
// FIXME if state=modified PDeactivate must be noop.
pyobj
.
pystate
=
nil
pyobj
.
serial
=
zodb
.
InvalidTID
}
...
...
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