Note that there are some explanatory texts on larger screens.

plurals
  1. POExecute Twisted reactor.run() in a thread?
    primarykey
    data
    text
    <p>I'm trying to make a Python library to use the Ubutu One API from Objective-C. Here is my source code: <a href="https://github.com/JoseExposito/U1-Finder-Plugin/blob/master/U1FinderLib/U1FinderLib.py" rel="noreferrer">https://github.com/JoseExposito/U1-Finder-Plugin/blob/master/U1FinderLib/U1FinderLib.py</a></p> <p>I need to make many calls to the API, for this reason I need to have my reactor running once instead of run it and stop it, like in the example of the Ubuntu One documentation: <a href="https://one.ubuntu.com/developer/files/store_files/syncdaemontool" rel="noreferrer">https://one.ubuntu.com/developer/files/store_files/syncdaemontool</a></p> <p>Because it is not possible to run twice the reactor... And I need to execute reactor.run() in a thread because I can not block the application that uses that library!</p> <p>It is possible to do that? I'm not able to run the reactor in a thread and call the Ubuntu One API synchronous.</p> <p>EDIT:</p> <p>I'm using this simple source code to test the idea:</p> <pre><code>#!/usr/bin/env python import objc import thread import os import time from twisted.internet import reactor, defer from ubuntuone.platform.tools import (SyncDaemonTool, is_already_running) from threading import Thread NSObject = objc.lookUpClass('NSObject') ## # Variable to get the result of the calls to the Sync Daemon. # The result is a JSON string stored in returned_value[0]. returned_value = [''] ## # Objective-C facade to the methods of the U1FinderLib. class U1FinderLib(NSObject): def init(self): self = super(U1FinderLib, self).init() self.sync_daemon_tool = SyncDaemonTool(None) Thread(target=reactor.run, args=(False,)).start() return self @objc.typedSelector('@@:') def volumeList(self): print "Begin volumeList" reactor.callLater(0, run_command, "volume_list", [], self.sync_daemon_tool) print "End volumeList" return returned_value[0] ## # Auxiliar functions to call to the sync daemon. @defer.inlineCallbacks def run_command(action, params, sync_daemon_tool): print "run_command" running = yield is_already_running() print "After is_already_running" try: if not running: returned_value[0] = '{ type:"error" reason:"Sync Daemon is not running" }' else: print "Before run_action" yield run_action(action, params, sync_daemon_tool) print "After run_action" except Exception, e: returned_value[0] = '{ type:"error" reason:"Exception: %s" }' % e @defer.inlineCallbacks def run_action(action, params, sync_daemon_tool): if action == "volume_list": d = sync_daemon_tool.get_folders() returned_value[0] = yield d.addCallback(lambda r: volume_list(r)) # Volume List def volume_list(folders): volumes_json = '{ type:"volume_list" volumes: { \n\t{ volume:"' + os.path.expanduser('~/Ubuntu One') + '" subscribed:"YES" }' for folder in folders: volumes_json += ',\n\t{ volume:"' + folder['path'] + '" subscribed:"' + ('YES' if bool(folder['subscribed']) else 'NO') + '" }' volumes_json += '\n} }' return volumes_json if __name__ == '__main__': py = U1FinderLib.alloc().init() print py.volumeList() print "EXIT" </code></pre> <p>And this is the output of the program:</p> <pre><code>Begin volumeList End volumeList EXIT </code></pre> <p>The problem is that the "run_command" function is never called</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload