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
171cdb09
Commit
171cdb09
authored
Jul 13, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
1bbc897a
Changes
1
Show 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