Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZODB
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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
ZODB
Commits
62a611a1
Commit
62a611a1
authored
Mar 11, 2005
by
Tim Peters
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ZODB is an XXX-free zone now.
parent
a8ed2766
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
36 additions
and
54 deletions
+36
-54
doc/zdctl.txt
doc/zdctl.txt
+2
-2
src/Persistence/tests/test_mapping.py
src/Persistence/tests/test_mapping.py
+1
-2
src/ZEO/TransactionBuffer.py
src/ZEO/TransactionBuffer.py
+1
-1
src/ZEO/tests/zeoserver.py
src/ZEO/tests/zeoserver.py
+1
-2
src/ZEO/zrpc/trigger.py
src/ZEO/zrpc/trigger.py
+1
-1
src/ZODB/TmpStore.py
src/ZODB/TmpStore.py
+2
-2
src/ZODB/component.xml
src/ZODB/component.xml
+2
-2
src/ZODB/tests/TransactionalUndoStorage.py
src/ZODB/tests/TransactionalUndoStorage.py
+1
-1
src/ZODB/tests/VersionStorage.py
src/ZODB/tests/VersionStorage.py
+5
-7
src/ZODB/transact.py
src/ZODB/transact.py
+1
-1
src/persistent/TimeStamp.c
src/persistent/TimeStamp.c
+3
-4
src/persistent/tests/test_pickle.py
src/persistent/tests/test_pickle.py
+8
-15
src/persistent/tests/test_wref.py
src/persistent/tests/test_wref.py
+1
-2
src/persistent/wref.py
src/persistent/wref.py
+3
-4
src/scripts/zeoqueue.py
src/scripts/zeoqueue.py
+2
-2
src/scripts/zeoup.py
src/scripts/zeoup.py
+1
-1
src/transaction/_transaction.py
src/transaction/_transaction.py
+1
-4
src/transaction/tests/test_transaction.py
src/transaction/tests/test_transaction.py
+0
-1
No files found.
doc/zdctl.txt
View file @
62a611a1
...
@@ -326,10 +326,10 @@ script already has the appropriate magical comments for chkconfig.
...
@@ -326,10 +326,10 @@ script already has the appropriate magical comments for chkconfig.
zdctl reference
zdctl reference
---------------
---------------
XXX
TBD
TBD
zdrun reference
zdrun reference
---------------
---------------
XXX
TBD
TBD
src/Persistence/tests/test_mapping.py
View file @
62a611a1
...
@@ -11,8 +11,7 @@
...
@@ -11,8 +11,7 @@
# FOR A PARTICULAR PURPOSE.
# FOR A PARTICULAR PURPOSE.
#
#
##############################################################################
##############################################################################
"""XXX short summary goes here.
"""
$Id$
$Id$
"""
"""
import
unittest
import
unittest
...
...
src/ZEO/TransactionBuffer.py
View file @
62a611a1
...
@@ -44,7 +44,7 @@ class TransactionBuffer:
...
@@ -44,7 +44,7 @@ class TransactionBuffer:
# can happen in Python if one thread closes a file that another
# can happen in Python if one thread closes a file that another
# thread is reading. In a debug build, an assert() can fail.
# thread is reading. In a debug build, an assert() can fail.
#
XXX
If an operation is performed on a closed TransactionBuffer,
#
Caution:
If an operation is performed on a closed TransactionBuffer,
# it has no effect and does not raise an exception. The only time
# it has no effect and does not raise an exception. The only time
# this should occur is when a ClientStorage is closed in one
# this should occur is when a ClientStorage is closed in one
# thread while another thread is in its tpc_finish(). It's not
# thread while another thread is in its tpc_finish(). It's not
...
...
src/ZEO/tests/zeoserver.py
View file @
62a611a1
...
@@ -139,7 +139,7 @@ class Suicide(threading.Thread):
...
@@ -139,7 +139,7 @@ class Suicide(threading.Thread):
os
.
kill
(
pid
,
signal
.
SIGKILL
)
os
.
kill
(
pid
,
signal
.
SIGKILL
)
else
:
else
:
from
ZEO.tests.forker
import
shutdown_zeo_server
from
ZEO.tests.forker
import
shutdown_zeo_server
#
XXX
If the -k option was given to zeoserver, then the
#
Nott:
If the -k option was given to zeoserver, then the
# process will go away but the temp files won't get
# process will go away but the temp files won't get
# cleaned up.
# cleaned up.
shutdown_zeo_server
(
self
.
_adminaddr
)
shutdown_zeo_server
(
self
.
_adminaddr
)
...
@@ -167,7 +167,6 @@ def main():
...
@@ -167,7 +167,6 @@ def main():
zo
.
realize
([
"-C"
,
configfile
])
zo
.
realize
([
"-C"
,
configfile
])
zeo_port
=
int
(
zo
.
address
[
1
])
zeo_port
=
int
(
zo
.
address
[
1
])
# XXX a hack
if
zo
.
auth_protocol
==
"plaintext"
:
if
zo
.
auth_protocol
==
"plaintext"
:
import
ZEO.tests.auth_plaintext
import
ZEO.tests.auth_plaintext
...
...
src/ZEO/zrpc/trigger.py
View file @
62a611a1
...
@@ -117,7 +117,7 @@ if os.name == 'posix':
...
@@ -117,7 +117,7 @@ if os.name == 'posix':
else
:
else
:
#
XXX
Should define a base class that has the common methods and
#
TODO:
Should define a base class that has the common methods and
# then put the platform-specific in a subclass named trigger.
# then put the platform-specific in a subclass named trigger.
# win32-safe version
# win32-safe version
...
...
src/ZODB/TmpStore.py
View file @
62a611a1
...
@@ -61,7 +61,7 @@ class TmpStore:
...
@@ -61,7 +61,7 @@ class TmpStore:
serial
=
h
[:
8
]
serial
=
h
[:
8
]
return
self
.
_file
.
read
(
size
),
serial
return
self
.
_file
.
read
(
size
),
serial
#
XXX
clarify difference between self._storage & self._db._storage
#
TODO:
clarify difference between self._storage & self._db._storage
def
modifiedInVersion
(
self
,
oid
):
def
modifiedInVersion
(
self
,
oid
):
if
self
.
_index
.
has_key
(
oid
):
if
self
.
_index
.
has_key
(
oid
):
...
@@ -118,6 +118,6 @@ class TmpStore:
...
@@ -118,6 +118,6 @@ class TmpStore:
return
()
return
()
def
versionEmpty
(
self
,
version
):
def
versionEmpty
(
self
,
version
):
#
XXX
what is this supposed to do?
#
TODO:
what is this supposed to do?
if
version
==
self
.
_bver
:
if
version
==
self
.
_bver
:
return
len
(
self
.
_index
)
return
len
(
self
.
_index
)
src/ZODB/component.xml
View file @
62a611a1
<component
prefix=
"ZODB.config"
>
<component
prefix=
"ZODB.config"
>
<!--
XXX
needs descriptions for everything -->
<!--
TODO
needs descriptions for everything -->
<abstracttype
name=
"ZODB.storage"
/>
<abstracttype
name=
"ZODB.storage"
/>
<abstracttype
name=
"ZODB.database"
/>
<abstracttype
name=
"ZODB.database"
/>
...
@@ -95,7 +95,7 @@
...
@@ -95,7 +95,7 @@
<key
name=
"var"
>
<key
name=
"var"
>
<description>
<description>
The directory where persistent cache files are stored. By
The directory where persistent cache files are stored. By
default cache files, if they are persistent, are stored in
default cache files, if they are persistent, are stored in
the current directory.
the current directory.
</description>
</description>
</key>
</key>
...
...
src/ZODB/tests/TransactionalUndoStorage.py
View file @
62a611a1
...
@@ -603,7 +603,7 @@ class TransactionalUndoStorage:
...
@@ -603,7 +603,7 @@ class TransactionalUndoStorage:
self
.
_storage
.
pack
(
t
,
referencesf
)
self
.
_storage
.
pack
(
t
,
referencesf
)
cn
.
sync
()
cn
.
sync
()
#
XXX
Is _cache supposed to have a clear() method, or not?
#
TODO:
Is _cache supposed to have a clear() method, or not?
# cn._cache.clear()
# cn._cache.clear()
# The last undo set the value to 3 and pack should
# The last undo set the value to 3 and pack should
...
...
src/ZODB/tests/VersionStorage.py
View file @
62a611a1
...
@@ -186,7 +186,7 @@ class VersionStorage:
...
@@ -186,7 +186,7 @@ class VersionStorage:
eq
=
self
.
assertEqual
eq
=
self
.
assertEqual
oid
,
version
=
self
.
_setup_version
()
oid
,
version
=
self
.
_setup_version
()
#
XXX
Not sure I can write a test for getSerial() in the
# Not sure I can write a test for getSerial() in the
# presence of aborted versions, because FileStorage and
# presence of aborted versions, because FileStorage and
# Berkeley storage give a different answer. I think Berkeley
# Berkeley storage give a different answer. I think Berkeley
# is right and FS is wrong.
# is right and FS is wrong.
...
@@ -219,9 +219,8 @@ class VersionStorage:
...
@@ -219,9 +219,8 @@ class VersionStorage:
self
.
_storage
.
tpc_begin
(
t
)
self
.
_storage
.
tpc_begin
(
t
)
# And try to abort the empty version
# And try to abort the empty version
if
(
hasattr
(
self
.
_storage
,
'supportsTransactionalUndo'
)
if
(
hasattr
(
self
.
_storage
,
'supportsTransactionalUndo'
)
and
and
self
.
_storage
.
supportsTransactionalUndo
()):
self
.
_storage
.
supportsTransactionalUndo
()):
# XXX FileStorage used to be broken on this one
self
.
assertRaises
(
POSException
.
VersionError
,
self
.
assertRaises
(
POSException
.
VersionError
,
self
.
_storage
.
abortVersion
,
self
.
_storage
.
abortVersion
,
''
,
t
)
''
,
t
)
...
@@ -236,9 +235,8 @@ class VersionStorage:
...
@@ -236,9 +235,8 @@ class VersionStorage:
eq
(
zodb_unpickle
(
data
),
MinPO
(
51
))
eq
(
zodb_unpickle
(
data
),
MinPO
(
51
))
def
checkCommitVersionErrors
(
self
):
def
checkCommitVersionErrors
(
self
):
if
not
(
hasattr
(
self
.
_storage
,
'supportsTransactionalUndo'
)
if
not
(
hasattr
(
self
.
_storage
,
'supportsTransactionalUndo'
)
and
and
self
.
_storage
.
supportsTransactionalUndo
()):
self
.
_storage
.
supportsTransactionalUndo
()):
# XXX FileStorage used to be broken on this one
return
return
eq
=
self
.
assertEqual
eq
=
self
.
assertEqual
oid1
,
version1
=
self
.
_setup_version
(
'one'
)
oid1
,
version1
=
self
.
_setup_version
(
'one'
)
...
...
src/ZODB/transact.py
View file @
62a611a1
...
@@ -33,7 +33,7 @@ def transact(f, note=None, retries=5):
...
@@ -33,7 +33,7 @@ def transact(f, note=None, retries=5):
TransactionError occurs, the transaction will not be retried.
TransactionError occurs, the transaction will not be retried.
"""
"""
#
XXX
deal with ZEO disconnected errors?
#
TODO:
deal with ZEO disconnected errors?
def
g
(
*
args
,
**
kwargs
):
def
g
(
*
args
,
**
kwargs
):
n
=
retries
n
=
retries
...
...
src/persistent/TimeStamp.c
View file @
62a611a1
/*****************************************************************************
/*****************************************************************************
Copyright (c) 2001, 2004 Zope Corporation and Contributors.
Copyright (c) 2001, 2004 Zope Corporation and Contributors.
All Rights Reserved.
All Rights Reserved.
This software is subject to the provisions of the Zope Public License,
This software is subject to the provisions of the Zope Public License,
...
@@ -43,7 +43,7 @@ static short joff[2][12] = {
...
@@ -43,7 +43,7 @@ static short joff[2][12] = {
static
double
gmoff
=
0
;
static
double
gmoff
=
0
;
/*
XXX should this be stored in sconv?
*/
/*
TODO: May be better (faster) to store in a file static.
*/
#define SCONV ((double)60) / ((double)(1<<16)) / ((double)(1<<16))
#define SCONV ((double)60) / ((double)(1<<16)) / ((double)(1<<16))
static
int
static
int
...
@@ -121,7 +121,6 @@ TimeStamp_hash(TimeStamp *self)
...
@@ -121,7 +121,6 @@ TimeStamp_hash(TimeStamp *self)
register
unsigned
char
*
p
=
(
unsigned
char
*
)
self
->
data
;
register
unsigned
char
*
p
=
(
unsigned
char
*
)
self
->
data
;
register
int
len
=
8
;
register
int
len
=
8
;
register
long
x
=
*
p
<<
7
;
register
long
x
=
*
p
<<
7
;
/* XXX unroll loop? */
while
(
--
len
>=
0
)
while
(
--
len
>=
0
)
x
=
(
1000003
*
x
)
^
*
p
++
;
x
=
(
1000003
*
x
)
^
*
p
++
;
x
^=
8
;
x
^=
8
;
...
@@ -131,7 +130,7 @@ TimeStamp_hash(TimeStamp *self)
...
@@ -131,7 +130,7 @@ TimeStamp_hash(TimeStamp *self)
}
}
typedef
struct
{
typedef
struct
{
/*
XXX
reverse-engineer what's in these things and comment them */
/*
TODO:
reverse-engineer what's in these things and comment them */
int
y
;
int
y
;
int
m
;
int
m
;
int
d
;
int
d
;
...
...
src/persistent/tests/test_pickle.py
View file @
62a611a1
...
@@ -71,7 +71,7 @@ def test_basic_pickling():
...
@@ -71,7 +71,7 @@ def test_basic_pickling():
>>> pickle.loads(pickle.dumps(x, 1)) == x
>>> pickle.loads(pickle.dumps(x, 1)) == x
1
1
XXX disable until Python 2.3.4
>>> pickle.loads(pickle.dumps(x, 2)) == x
>>> pickle.loads(pickle.dumps(x, 2)) == x
1
1
>>> x.__setstate__({'z': 1})
>>> x.__setstate__({'z': 1})
...
@@ -121,8 +121,7 @@ def test_pickling_w_overrides():
...
@@ -121,8 +121,7 @@ def test_pickling_w_overrides():
1
1
>>> pickle.loads(pickle.dumps(x, 1)) == x
>>> pickle.loads(pickle.dumps(x, 1)) == x
1
1
>>> pickle.loads(pickle.dumps(x, 2)) == x
XXX disable until Python 2.3.4 >>> pickle.loads(pickle.dumps(x, 2)) == x
1
1
"""
"""
...
@@ -160,8 +159,7 @@ def test_pickling_w_slots_only():
...
@@ -160,8 +159,7 @@ def test_pickling_w_slots_only():
1
1
>>> pickle.loads(pickle.dumps(x, 1)) == x
>>> pickle.loads(pickle.dumps(x, 1)) == x
1
1
>>> pickle.loads(pickle.dumps(x, 2)) == x
XXX disable until Python 2.3.4 >>> pickle.loads(pickle.dumps(x, 2)) == x
1
1
>>> x.s4 = 'spam'
>>> x.s4 = 'spam'
...
@@ -177,8 +175,7 @@ def test_pickling_w_slots_only():
...
@@ -177,8 +175,7 @@ def test_pickling_w_slots_only():
1
1
>>> pickle.loads(pickle.dumps(x, 1)) == x
>>> pickle.loads(pickle.dumps(x, 1)) == x
1
1
>>> pickle.loads(pickle.dumps(x, 2)) == x
XXX disable until Python 2.3.4 >>> pickle.loads(pickle.dumps(x, 2)) == x
1
1
"""
"""
...
@@ -212,8 +209,7 @@ def test_pickling_w_slots():
...
@@ -212,8 +209,7 @@ def test_pickling_w_slots():
1
1
>>> pickle.loads(pickle.dumps(x, 1)) == x
>>> pickle.loads(pickle.dumps(x, 1)) == x
1
1
>>> pickle.loads(pickle.dumps(x, 2)) == x
XXX disable until Python 2.3.4 >>> pickle.loads(pickle.dumps(x, 2)) == x
1
1
>>> x.s4 = 'spam'
>>> x.s4 = 'spam'
...
@@ -230,8 +226,7 @@ def test_pickling_w_slots():
...
@@ -230,8 +226,7 @@ def test_pickling_w_slots():
1
1
>>> pickle.loads(pickle.dumps(x, 1)) == x
>>> pickle.loads(pickle.dumps(x, 1)) == x
1
1
>>> pickle.loads(pickle.dumps(x, 2)) == x
XXX disable until Python 2.3.4 >>> pickle.loads(pickle.dumps(x, 2)) == x
1
1
"""
"""
...
@@ -252,8 +247,7 @@ def test_pickling_w_slots_w_empty_dict():
...
@@ -252,8 +247,7 @@ def test_pickling_w_slots_w_empty_dict():
1
1
>>> pickle.loads(pickle.dumps(x, 1)) == x
>>> pickle.loads(pickle.dumps(x, 1)) == x
1
1
>>> pickle.loads(pickle.dumps(x, 2)) == x
XXX disable until Python 2.3.4 >>> pickle.loads(pickle.dumps(x, 2)) == x
1
1
>>> x.s4 = 'spam'
>>> x.s4 = 'spam'
...
@@ -270,8 +264,7 @@ def test_pickling_w_slots_w_empty_dict():
...
@@ -270,8 +264,7 @@ def test_pickling_w_slots_w_empty_dict():
1
1
>>> pickle.loads(pickle.dumps(x, 1)) == x
>>> pickle.loads(pickle.dumps(x, 1)) == x
1
1
>>> pickle.loads(pickle.dumps(x, 2)) == x
XXX disable until Python 2.3.4 >>> pickle.loads(pickle.dumps(x, 2)) == x
1
1
"""
"""
...
...
src/persistent/tests/test_wref.py
View file @
62a611a1
...
@@ -11,8 +11,7 @@
...
@@ -11,8 +11,7 @@
# FOR A PARTICULAR PURPOSE.
# FOR A PARTICULAR PURPOSE.
#
#
##############################################################################
##############################################################################
"""XXX short summary goes here.
"""
$Id$
$Id$
"""
"""
import
unittest
import
unittest
...
...
src/persistent/wref.py
View file @
62a611a1
...
@@ -234,9 +234,8 @@ class PersistentWeakKeyDictionary(Persistent):
...
@@ -234,9 +234,8 @@ class PersistentWeakKeyDictionary(Persistent):
>>> db.close()
>>> db.close()
"""
"""
# XXX it is expensive trying to load dead objects from the database.
# TODO: It's expensive trying to load dead objects from the database.
# It would be helpful if the data manager/connection cached these.
# It would be helpful if the data manager/connection cached these.
def
__init__
(
self
,
adict
=
None
,
**
kwargs
):
def
__init__
(
self
,
adict
=
None
,
**
kwargs
):
self
.
data
=
{}
self
.
data
=
{}
...
@@ -298,4 +297,4 @@ class PersistentWeakKeyDictionary(Persistent):
...
@@ -298,4 +297,4 @@ class PersistentWeakKeyDictionary(Persistent):
for
k
,
v
in
adict
.
items
():
for
k
,
v
in
adict
.
items
():
self
.
data
[
WeakRef
(
k
)]
=
v
self
.
data
[
WeakRef
(
k
)]
=
v
#
XXX Someone else can fill out the rest of the methods, with tests. :)
#
TODO: May need more methods, and tests.
src/scripts/zeoqueue.py
View file @
62a611a1
...
@@ -115,7 +115,7 @@ class Status:
...
@@ -115,7 +115,7 @@ class Status:
-
The
number
of
currently
active
transactions
.
-
The
number
of
currently
active
transactions
.
-
The
number
of
reported
queued
transactions
.
-
The
number
of
reported
queued
transactions
.
-
Client
restarts
.
-
Client
restarts
.
-
Number
of
current
connections
.
XXX
(
This
might
not
be
useful
.)
-
Number
of
current
connections
(
but
this
might
not
be
useful
).
We
can
observe
these
events
by
reading
the
following
sorts
of
log
We
can
observe
these
events
by
reading
the
following
sorts
of
log
entries
:
entries
:
...
@@ -191,7 +191,7 @@ class Status:
...
@@ -191,7 +191,7 @@ class Status:
if
mo
is
None
:
if
mo
is
None
:
return
return
called_method
=
mo
.
group
(
'method'
)
called_method
=
mo
.
group
(
'method'
)
#
XXX exit earlier
if we've got zeoLoad, because it's the most
#
Exit early
if we've got zeoLoad, because it's the most
# frequently called method and we don't use it.
# frequently called method and we don't use it.
if
called_method
==
"zeoLoad"
:
if
called_method
==
"zeoLoad"
:
return
return
...
...
src/scripts/zeoup.py
View file @
62a611a1
...
@@ -44,7 +44,7 @@ ZEO_VERSION = 2
...
@@ -44,7 +44,7 @@ ZEO_VERSION = 2
def
check_server
(
addr
,
storage
,
write
):
def
check_server
(
addr
,
storage
,
write
):
t0
=
time
.
time
()
t0
=
time
.
time
()
if
ZEO_VERSION
==
2
:
if
ZEO_VERSION
==
2
:
#
XXX should do retries w/ exponential backoff
#
TODO: should do retries w/ exponential backoff.
cs
=
ClientStorage
(
addr
,
storage
=
storage
,
wait
=
0
,
cs
=
ClientStorage
(
addr
,
storage
=
storage
,
wait
=
0
,
read_only
=
(
not
write
))
read_only
=
(
not
write
))
else
:
else
:
...
...
src/transaction/_transaction.py
View file @
62a611a1
...
@@ -54,7 +54,7 @@ methods and support a second argument to tpc_begin().
...
@@ -54,7 +54,7 @@ methods and support a second argument to tpc_begin().
The second argument to tpc_begin() indicates that a subtransaction
The second argument to tpc_begin() indicates that a subtransaction
commit is beginning (if it is true). In a subtransaction, there is no
commit is beginning (if it is true). In a subtransaction, there is no
tpc_vote() call
. (XXX: I don't have any idea why.)
The tpc_finish()
tpc_vote() call
(I don't know why not).
The tpc_finish()
or tpc_abort() call applies just to that subtransaction.
or tpc_abort() call applies just to that subtransaction.
Once a resource manager is involved in a subtransaction, all
Once a resource manager is involved in a subtransaction, all
...
@@ -128,9 +128,6 @@ manager calls beforeCompletion() when it starts a top-level two-phase
...
@@ -128,9 +128,6 @@ manager calls beforeCompletion() when it starts a top-level two-phase
commit. It calls afterCompletion() when a top-level transaction is
commit. It calls afterCompletion() when a top-level transaction is
committed or aborted. The methods are passed the current Transaction
committed or aborted. The methods are passed the current Transaction
as their only argument.
as their only argument.
XXX This code isn't tested.
"""
"""
import
logging
import
logging
...
...
src/transaction/tests/test_transaction.py
View file @
62a611a1
...
@@ -203,7 +203,6 @@ class TransactionTests(unittest.TestCase):
...
@@ -203,7 +203,6 @@ class TransactionTests(unittest.TestCase):
assert
self
.
nosub1
.
_p_jar
.
ctpc_finish
==
0
assert
self
.
nosub1
.
_p_jar
.
ctpc_finish
==
0
assert
self
.
nosub1
.
_p_jar
.
cabort
==
1
assert
self
.
nosub1
.
_p_jar
.
cabort
==
1
# XXX:
def
BUGtestNSJSubTransactionCommitAbort
(
self
):
def
BUGtestNSJSubTransactionCommitAbort
(
self
):
"""
"""
this reveals a bug in transaction.py
this reveals a bug in transaction.py
...
...
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