[Twisted-Python] locking threads when deferToThread is used

Jean-Paul Calderone exarkun at divmod.com
Wed Aug 8 08:04:57 EDT 2007


On Wed, 08 Aug 2007 13:11:09 +0200, Ladislav Andel <ladaan at iptel.org> wrote:
>Jean-Paul Calderone wrote:
>>On Wed, 08 Aug 2007 09:56:16 +0200, Ladislav Andel <ladaan at iptel.org> 
>>wrote:
>>>Hi,
>>>I'm writing an application which will be periodically testing servers.
>>>I will have a global list of these servers(domain names) and need to do
>>>few tasks.
>>>1) DNS checks - I will use asynchronous twisted-names for it
>>>- in case there is a difference comparing to the list it should update the 
>>>list(then also in DB)
>>>2) ICMP pings - should be also possible to do it asynchronously
>>>3) Blocking function which will be pinging with SIP requests
>>>- here I will use function deferToThread to make it non-blocking.
>>>
>>>Questions:
>>>1) How do I lock each thread when writing to a global list in twisted?
>>
>>Don't.  Don't share state between different threads.  If you need to mutate
>>state as a result of code which has run in a thread, do it in the reactor
>>thread based on the result of the Deferred returned by deferToThread.
>I'm aiming to use results of the Deffered returned by deferToThread.
>Can you give me an example of combining two Deferred results?
>This will be done through callbacks but what if the blocking application 
>gives me result in 5 sec
>and e.g. DNS check in 1 sec.

twisted.internet.defer.gatherResults takes a list of Deferreds and returns
a Deferred which fires with a list of results.  If you want to wait for both
results, you can use this.  If you only want the first result, whichever
that may be, then you just need to write a little class that acknowledges
the first Deferred's callback and disregards callbacks from any subsequent
Deferreds.

>>Also, why do you need threads to send SIP messages?
>I use third party application where I'm just handling parameters to the 
>application.
>I know it's possible to do it somehow easily via twisted but I don't have 
>time to explore it now.
>I'm also quite new to python and also to twisted so that's why I don't want 
>to get involved in something more
>complex for now.

Alright.

>>
>>>2) How will I put together all three results mentioned above in the global 
>>>list
>>>- is it by using function callLater ?
>>
>>Don't use globals.  You can just put your state variables on an instance of
>>a class.  There's nothing unique to Twisted about this.  I'm not sure how
>>callLater would be involved.  callLater is for scheduling functions to run
>>based on timing events.
>Can you give me a little example?

I'm not really sure what you have in mind, but maybe an approach along these
lines would be useful:

class PingTracker:
    def __init__(self):
        self.dns = None
        self.sip = None
        self.ping = None

    def check(self, host):
        checks = []
        checks.append(checkDNS().addCallback(self.setDNSResult))
        checks.append(checkSIP().addCallback(self.setSIPResult))
        checks.append(checkPing().addCallback(self.setPingResult))
        return gatherResults(checks)

    def setDNSResult(self, result):
        self.dns = result

    ...

Jean-Paul




More information about the Twisted-Python mailing list