Hello,
We are transferring data on a FTP from Plone.
Every transfer is starting by acquiring a lock put the file then
releasing the lock.
If the FTP server is unreachable or the lock cannot be acquired we want
to launch again the transfer later.
Nothing is write in the ZODB.
We want to use async to not block the user on such job.
The first thing that was not clear for me was that le retry policy is
only transaction (ZODB) centric. Our process doesn't write in the ZODB,
then the NeverRetry policy seems to be the better to use.
How can I use the success and the failure callback ?
In the success callback the 'context' is the value returned by job
function. From there almost everything is not available:
ipdb> getToolByName(getSite(), 'MailHost')
*** AttributeError: MailHost
ipdb> getUtility(IURLTool)
*** ComponentLookupError: (<InterfaceClass Products...IURLTool>, '')
ipdb> getUtility(IMailHost)
*** ComponentLookupError: (<InterfaceClass Products...IMailHost>, '')
In the failure callback the 'context' is build with several data from
the error context. But it's still unusable like the success callback.
We can also register handlers but we cannot filter jobs:
>>> from zope.component import provideHandler
>>> from plone.app.async.interfaces import IJobSuccess, IJobFailure
>>> provideHandler(successHandler, [IJobSuccess])
>>> provideHandler(failureHandler, [IJobFailure])
Success case:
ipdb> event.object
Out[0]: True
ipdb> event.__dict__
Out[0]: {'object': True}
Failure case:
ipdb> event
Out[0]: <plone.app.async.interfaces.JobFailure object at 0xe193210>
ipdb> event.__dict__
ipdb> Out[0]: {'object': <zc.twist.Failure failure test>}
The problem is the same than above.
How can I relaunch the job after it fails ?
Here an example of the code:
def inDelivery(ob, event):
""" Build and send the IFCSUM Message
"""
ifcsul = createMessage()
## IFCSUM Message Async Sending
async = getUtility(IAsyncService)
job = async.queueJob(sendIfcsumMessage, ob,
ifcsum.getMessage(), ifcsum.getUID())
job.addCallbacks(success=IFCSUMSuccessCallback,
failure=IFCSUMFailureCallback,
failure_log_level=WARNING,
retry_policy_factory=NeverRetry)
def IFCSUMFailureCallback(context):
""" Async Job Failure in Sending the FTP Message
"""
pass
def IFCSUMSuccessCallback(context):
""" Async Job Success in Sending the FTP Message
"""
pass
def sendIfcsumMessage(context, message, uid):
""" Push the IFCSUM message by FTP
"""
ftp = None
if not isinstance(message, StringIO):
raise TypeError("'message' must be a StringIO")
try:
try:
ftp = FTP(host='x.x.x.x',user='xxx', passwd='xxxxx')
ftp.set_debuglevel(2)
ftp.set_pasv(0)
ftp.storlines(FTP_OUR_LOCK_FILENAME, StringIO('NOT EMPTY'))
if FTP_THEIR_LOCK_FILENAME in map(str.lower, ftp.nlst()):
#
raise ValueError("Lock file found: Abandon")
ftp.storlines('%s.xml' % uid, message)
finally:
if ftp is not None:
if FTP_OUR_LOCK_FILENAME in map(str.lower, ftp.nlst()):
ftp.delete(FTP_OUR_LOCK_FILENAME)
ftp.close()
except ftp_all_errors+(ValueError,), msg:
sendMail(msg)
raise
--
Encolpe DEGOUTE
Zope/Plone Consultant
Quadra Informatique
_______________________________________________
Product-Developers mailing list
[email protected]
https://lists.plone.org/mailman/listinfo/plone-product-developers