Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
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
alecs_myu
erp5
Commits
2d2c38f9
Commit
2d2c38f9
authored
Jun 28, 2013
by
Aurel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement better deletion mecanism & remove workflow transition overhead
parent
1b4cd9c7
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
323 additions
and
219 deletions
+323
-219
product/ERP5SyncML/Document/SyncMLSubscription.py
product/ERP5SyncML/Document/SyncMLSubscription.py
+276
-169
product/ERP5SyncML/Engine/AsynchronousEngine.py
product/ERP5SyncML/Engine/AsynchronousEngine.py
+15
-19
product/ERP5SyncML/Engine/EngineMixin.py
product/ERP5SyncML/Engine/EngineMixin.py
+7
-6
product/ERP5SyncML/Engine/SynchronousEngine.py
product/ERP5SyncML/Engine/SynchronousEngine.py
+9
-11
product/ERP5SyncML/Tool/SynchronizationTool.py
product/ERP5SyncML/Tool/SynchronizationTool.py
+9
-13
product/ERP5SyncML/tests/testERP5SyncML.py
product/ERP5SyncML/tests/testERP5SyncML.py
+7
-1
No files found.
product/ERP5SyncML/Document/SyncMLSubscription.py
View file @
2d2c38f9
This diff is collapsed.
Click to expand it.
product/ERP5SyncML/Engine/AsynchronousEngine.py
View file @
2d2c38f9
...
...
@@ -78,7 +78,10 @@ class SyncMLAsynchronousEngine(EngineMixin):
syncml_response
=
self
.
_generateBaseResponse
(
subscription
)
syncml_response
.
addFinal
()
else
:
self
.
runGetAndActivate
(
subscription
=
subscription
,
tag
=
tag
)
# Make sure it is launched after indexation step
self
.
runGetAndActivate
(
subscription
=
subscription
,
tag
=
tag
,
after_method_id
=
(
"getAndIndex"
,
"SQLCatalog_indexSyncMLSignatureList"
))
syncml_logger
.
info
(
"X-> Client is sendind modification in activities"
)
# As we generated all activities to send data at once, process must not
# go back here, go into processing state thus status will be applied and
...
...
@@ -163,10 +166,10 @@ class SyncMLAsynchronousEngine(EngineMixin):
# Apply command & send modifications
# Apply status about object send & synchronized if any
s
ync_status_counter
=
s
elf
.
_readStatusList
(
syncml_request
,
subscriber
,
self
.
_readStatusList
(
syncml_request
,
subscriber
,
generate_alert
=
True
)
syncml_response
=
None
tag
=
subscri
ption_path
=
subscri
ber
.
getRelativeUrl
()
tag
=
subscriber
.
getRelativeUrl
()
after_method_id
=
None
if
subscriber
.
getSynchronizationState
()
==
"sending_modifications"
:
if
syncml_request
.
isFinal
:
...
...
@@ -202,15 +205,13 @@ class SyncMLAsynchronousEngine(EngineMixin):
if
syncml_request
.
isFinal
:
# Server then sends its modifications
subscriber
.
sendModifications
()
# Now that everything is ok, init sync information
if
subscriber
.
getSyncmlAlertCode
()
not
in
(
"one_way_from_client"
,
"refresh_from_client_only"
):
# Reset signature only if we have to check modifications on server side
subscriber
.
initialiseSynchronization
()
# Run indexation only once client have sent its modifications
subscriber
.
indexSourceData
()
# Start to send modification only once we have processed
# all message from client
after_method_id
=
'processServerSynchronization'
,
after_method_id
=
(
'processServerSynchronization'
,
'SQLCatalog_indexSyncMLDocumentList'
)
# XXX after tag might also be required to make sure all data are indexed
tag
=
(
tag
,
"%s_reset"
%
subscriber
.
getPath
(),)
# Do not continue in elif, as sending modifications is done in the same
# package as sending notifications
...
...
@@ -242,10 +243,9 @@ class SyncMLAsynchronousEngine(EngineMixin):
after_tag
=
tag
).
sendMessage
(
xml
=
str
(
syncml_response
))
def
runGetAndActivate
(
self
,
subscription
,
tag
,
after_method_id
=
None
):
"""
Generate tag and method parameter and call the getAndActivate method
Launch the browsing of GID that will call the generation of syncml commands
"""
activate_kw
=
{
'activity'
:
'SQLQueue'
,
...
...
@@ -253,20 +253,16 @@ class SyncMLAsynchronousEngine(EngineMixin):
'tag'
:
tag
,
'priority'
:
ACTIVITY_PRIORITY
}
method_kw
=
{
'subscription_path'
:
subscription
.
getRelativeUrl
(),
}
pref
=
getSite
().
portal_preferences
subscription
.
getAndActivate
(
callback
=
"sendSyncCommand"
,
method_kw
=
method_kw
,
activate_kw
=
activate_kw
,
packet_size
=
pref
.
getPreferredDocumentRetrievedPerActivityCount
(),
activity_count
=
pref
.
getPreferredRetrievalActivityCount
(),
)
#
Then get deleted documen
t
# this will send also the final message of this sync part
subscription
.
activate
(
after_tag
=
tag
).
_getDeletedData
()
#
then send the final message of this sync par
t
subscription
.
activate
(
after_tag
=
tag
,
priority
=
ACTIVITY_PRIORITY
+
1
).
_sendFinalMessage
()
return
True
...
...
product/ERP5SyncML/Engine/EngineMixin.py
View file @
2d2c38f9
...
...
@@ -145,9 +145,10 @@ class EngineMixin(object):
signature
=
domain
.
getSignatureFromGid
(
object_gid
)
if
status
[
'status_code'
]
==
resolveSyncmlStatusCode
(
'success'
):
if
signature
:
domain
.
z_delete_data_from_path
(
path
=
signature
.
getPath
())
domain
.
_delObject
(
signature
.
getId
())
else
:
raise
ValueError
(
"Found no signature to delete
"
)
raise
ValueError
(
"Found no signature to delete
for gid %s"
%
(
object_gid
,)
)
else
:
raise
ValueError
(
"Unknown status code : %r"
%
(
status
[
'status_code'
],))
syncml_logger
.
error
(
"
\
t
Object deleted %s"
%
...
...
@@ -191,10 +192,8 @@ class EngineMixin(object):
if
subscription
.
getAuthenticationState
()
!=
'logged_in'
:
# Workflow action
subscription
.
login
()
if
subscription
.
getSyncmlAlertCode
()
not
in
(
"one_way_from_server"
,
"refresh_from_server_only"
):
# Reset signature only if client send its modification to server
subscription
.
initialiseSynchronization
()
subscription
.
indexSourceData
(
client
=
True
)
# Create the package 1
syncml_response
=
SyncMLResponse
()
...
...
@@ -301,7 +300,9 @@ class EngineMixin(object):
'one_way_from_server'
,
'refresh_from_client_only'
,
'one_way_from_client'
):
# XXX Why re-editing here ?
# Make sure we update configuration based on publication data
# so that manual edition is propagated
# XXX Must check all properties that must be setted
subscriber
.
setXmlBindingGeneratorMethodId
(
publication
.
getXmlBindingGeneratorMethodId
())
subscriber
.
setConduitModuleId
(
publication
.
getConduitModuleId
())
...
...
product/ERP5SyncML/Engine/SynchronousEngine.py
View file @
2d2c38f9
...
...
@@ -29,6 +29,7 @@ from logging import getLogger
from
Products.ERP5SyncML.Engine.EngineMixin
import
EngineMixin
from
Products.ERP5SyncML.SyncMLConstant
import
SynchronizationError
from
Products.ERP5.ERP5Site
import
getSite
syncml_logger
=
getLogger
(
'ERP5SyncML'
)
...
...
@@ -81,13 +82,12 @@ class SyncMLSynchronousEngine(EngineMixin):
# We only get data from server
finished
=
True
else
:
finished
=
subscription
.
_getSyncMLData
(
syncml_response
=
syncml_response
,
)
finished
=
subscription
.
_getSyncMLData
(
syncml_response
=
syncml_response
,
min_gid
=
None
,
max_gid
=
None
)
syncml_logger
.
info
(
"-> Client sendind modification, finished %s"
%
(
finished
,))
if
finished
:
# Add deleted objets
subscription
.
_getDeletedData
(
syncml_response
=
syncml_response
)
#
subscription._getDeletedData(syncml_response=syncml_response)
# Notify that all modifications were sent
syncml_response
.
addFinal
()
# Will then start processing sync commands from server
...
...
@@ -191,10 +191,8 @@ class SyncMLSynchronousEngine(EngineMixin):
if
syncml_request
.
isFinal
:
# Server will now send its modifications
subscriber
.
sendModifications
()
if
subscriber
.
getSyncmlAlertCode
()
not
in
(
"one_way_from_client"
,
"refresh_from_client_only"
):
# Reset signature only if we have to check modifications on server side
subscriber
.
initialiseSynchronization
()
# Run indexation only once client has sent its modifications
subscriber
.
indexSourceData
()
# Do not continue in elif, as sending modifications is done in the same
# package as sending notifications
...
...
@@ -205,11 +203,11 @@ class SyncMLSynchronousEngine(EngineMixin):
# We only get data from client
finished
=
True
else
:
finished
=
subscriber
.
_getSyncMLData
(
syncml_response
=
syncml_respons
e
)
finished
=
subscriber
.
_getSyncMLData
(
syncml_response
=
syncml_response
,
min_gid
=
None
,
max_gid
=
Non
e
)
syncml_logger
.
info
(
"-> Server sendind data, finished %s"
%
(
finished
,))
if
finished
:
subscriber
.
_getDeletedData
(
syncml_response
=
syncml_response
)
#
subscriber._getDeletedData(syncml_response=syncml_response)
syncml_response
.
addFinal
()
subscriber
.
waitNotifications
()
# Do not go into finished here as we must wait for
...
...
product/ERP5SyncML/Tool/SynchronizationTool.py
View file @
2d2c38f9
...
...
@@ -399,13 +399,14 @@ class SynchronizationTool(BaseTool):
return
str
(
syncml_response
)
# As engines are not zodb objects, the tool acts as a placeholder for methods
# that need to be called in activities
def
applySyncCommand
(
self
,
subscription_path
,
response_message_id
,
activate_kw
,
**
kw
):
"""
This methods is intented to be called by asynchronous engine in activity to
apply sync commands for a subset of data
As engines are not zodb object, the tool acts as a placeholder for method
that need to be called in activities
"""
subscription
=
self
.
restrictedTraverse
(
subscription_path
)
assert
subscription
is
not
None
,
"Impossible to find subscription %s"
\
...
...
@@ -437,13 +438,11 @@ class SynchronizationTool(BaseTool):
def
sendSyncCommand
(
self
,
id_list
,
message_id
,
subscription_path
,
activate_kw
,
is_final_message
=
False
):
def
sendSyncCommand
(
self
,
g
id_list
,
message_id
,
subscription_path
,
activate_kw
,
first_call
=
False
,
last_call
=
False
):
"""
This methods is intented to be called by asynchronous engine in activity to
send sync commands for a subset of data
As engines are not zodb object, the tool acts as a placeholder for method
that need to be called in activities
"""
subscription
=
self
.
restrictedTraverse
(
subscription_path
)
assert
subscription
is
not
None
,
"Impossible to find subscription %s"
\
...
...
@@ -457,17 +456,14 @@ class SynchronizationTool(BaseTool):
source
=
subscription
.
getSubscriptionUrlString
())
syncml_response
.
addBody
()
subscription
.
_getSyncMLData
(
syncml_response
=
syncml_response
,
id_list
=
id_list
,
gid_list
=
gid_list
,
first_call
=
first_call
,
last_call
=
last_call
,
)
if
is_final_message
:
# Notify that all modifications were sent
syncml_response
.
addFinal
()
# Send the message in activity to prevent recomputing data in case of
# Send the message in activity to prevent recomputation of data in case of
# transport failure
# activate_kw["group_method_id"] = None
# activate_kw["group_method_cost"] = .05
...
...
product/ERP5SyncML/tests/testERP5SyncML.py
View file @
2d2c38f9
...
...
@@ -44,6 +44,7 @@ from Products.ERP5SyncML.Document import SyncMLSubscription
from
Products.ERP5SyncML.tests.testERP5SyncMLMixin
import
TestERP5SyncMLMixin
\
as
TestMixin
from
Products.ERP5Type.tests.backportUnittest
import
expectedFailure
from
_mysql_exceptions
import
OperationalError
class
TestERP5SyncMLMixin
(
TestMixin
):
...
...
@@ -98,6 +99,8 @@ class TestERP5SyncMLMixin(TestMixin):
def
afterSetUp
(
self
):
"""Setup."""
self
.
login
()
self
.
portal
.
z_drop_syncml
()
self
.
portal
.
z_create_syncml
()
# This test creates Person inside Person, so we modifiy type information to
# allow anything inside Person (we'll cleanup on teardown)
self
.
getTypesTool
().
getTypeInfo
(
'Person'
).
filter_content_types
=
0
...
...
@@ -228,6 +231,7 @@ class TestERP5SyncMLMixin(TestMixin):
result
=
portal_sync
.
processClientSynchronization
(
subscription
.
getPath
())
self
.
tic
()
nb_message
+=
1
self
.
tic
()
return
nb_message
def
synchronizeWithBrokenMessage
(
self
,
id
):
...
...
@@ -948,6 +952,8 @@ return [context[%r]]
person_server
.
manage_delObjects
(
self
.
id1
)
person_client1
=
self
.
getPersonClient1
()
person_client1
.
manage_delObjects
(
self
.
id2
)
# import ipdb
# ipdb.set_trace()
self
.
synchronize
(
self
.
sub_id1
)
self
.
synchronize
(
self
.
sub_id2
)
self
.
checkSynchronizationStateIsSynchronized
()
...
...
@@ -1543,7 +1549,7 @@ return [context[%r]]
self
.
assertEquals
(
client_person
.
getLastName
(),
self
.
last_name1
)
# reset for refresh sync
# after synchroniz
e, the client object retrieve value of
server
# after synchroniz
ation, the client retrieves value from
server
self
.
resetSignaturePublicationAndSubscription
()
self
.
synchronize
(
self
.
sub_id1
)
...
...
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