I'm still pretty new to twisted and feel I'm slowly getting the hang of it,
enough to realise that this line of code is probably going to block and not
do me any favours, the line is the first line in a resource.Resource
render_POST.
json_request = json.loads(request.content.read())
The resource.Resource is a child of another resource which is passed to
server.Site which is passed to internent.TCPServer.
The problem is I can't work out how I can read the post data from the
request in an …
[View More]async way.
I have a feeling I need to implement a protocol, I'm guessing a
LineReceiver but I can't figure out how I'd tie that in with my current
solution or specifically how the LineReceiver would even read
asynchronously to be honest..
Maybe the read is fine? I need the whole post data to do anything useful I
guess as I can't string to a json decoder that I'm aware of. Just it will
block everything up while I read, which shouldn't be long but I guess I'm
bound to the speed of the person posting.
Thanks all!
Paul
[View Less]
HI, there
I'm new to twisted, after reading the documents from twisted
websites, I got some questions:
1. Is there a 'development mode ' for twisted ? like django, you can
see your changes without restarting server.
2. Can I use django and twisted together? actually, I want to use
django's ORM inside twisted server, so that I can manipulate data
easily. I've try 'sob.py', but I can not figure it out how to use it .
On the other hand, django is …
[View More]synchronous, twisted is
asynchronous, how to use them together if we can ?
3. How to suppress logs that I do not need ? there are many logs in
twisted.log file, as shown in the follow:
2013-09-05 07:04:07+0800 [SSHChannel session (0) on SSHService
ssh-connection on ClientCommandTransport,client] remote eof
2013-09-05 07:04:07+0800 [SSHChannel session (0) on SSHService
ssh-connection on ClientCommandTransport,client] unhandled request for
Any suggestions would be appreciated. Thanks.
[View Less]
Hi Matthew -
I have a couple of idioms I use for #2 and #3 in your message. Here they
are.
#2)
For timer events, I create a function that when called, continuously
schedules itself again in the reactor, does some work for the current
tick, and then exits. I've used this down to 1-second intervals. If
you're looking for sub-millisecond level timing, this may not be
appropriate for your application.
def timerFunction(reactor):
reactor.callLater(1.0, timerFunction, reactor)
# do …
[View More]the work for this time tick
# etc etc
return
# Somewhere in main do this to kick it off
from twisted.internet import reactor
timerFunction(reactor)
#3)
For subprocesses, I like to create a custom protocol for each type of
sub-command I am calling. I also like to create an object to manage
the process, its arguments, its results and its temp files. The idiom
below is suitable for calling a subprocess that accepts a small amount
of buffered data on stdin, produces some output on stdout, and logs its
stderr.
Be careful examining the value of reason.value.exitCode in
processExited. The twisted docs show printing the exitCode as a "%d",
but sometimes the value is None --- if the process was terminated by a
signal. The mere printing of the value with "%d" will then trigger an
exception!
Here's my idiom:
class FooprocProtocol(protocol.ProcessProtocol):
def __init__(self, foomgr):
# the object managing my subprocess
self.foomgr = foomgr
# my stdout data
self.data = ""
def connectionMade(self):
# Pump input data in using this, and then close stdin
log.msg("connectionMade!")
# self.transport.write("...") # if there is any data to shove into
stdin
self.transport.closeStdin()
def outReceived(self, data):
# collect up our stdout
log.msg("outReceived! with %d bytes!" % len(data))
self.data = self.data + data
def errReceived(self, data):
# echo stderr messages to log with a marker
log.msg(">%s" % data)
def inConnectionLost(self):
print "inConnectionLost! stdin is closed! (we probably did it)"
def outConnectionLost(self):
log.msg("outConnectionLost! The child closed their stdout!")
def errConnectionLost(self):
log.msg("errConnectionLost! The child closed their stderr.")
def processExited(self, reason):
log.msg("processExited:%s:" % reason)
exitcode = reason.value.exitCode # an integer or None
# do some work upon processExit potentially make a decision on
exitcode ...
log.msg("processExited:%s" % exitcode)
def processEnded(self, reason):
print "processEnded, status %s" % (reason.value.exitCode,)
# process the data in the process manager
exitcode = reason.value.exitCode # might be non-numeric
result = self.foomgr.processData(exitcode)
# The main job of the Process Manager is to build the command list and
# process the results. It gives us a handy place to encapsulate this
# logic.
class FooprocManager(object):
CMD = "/usr/local/foocmd"
def __init__(self, arg1, arg2, arg3)
# create a Deferred to fire when we succeed or fail
self.d = Deferred()
# build our command argument list as appropriate for our command
self.cmdargs = self.build_cmd_args(arg1, arg2, arg3)
# define places to store the transport, pid and other things
self.ptransport = None
self.pid = None
def build_cmd_args(self, arg1, arg2, arg3):
# in my projects, this method has become fairly involved as it
creates
# tmp files and builds potentially complicated argument lists.
arglist = [self.CMD, arg1, arg2, arg3]
return arglist
def run(self):
# instantiate a protocol connected to this manager
pp = FooprocProtocol(self)
# spawn the process, save the PID
self.ptransport = reactor.spawnProcess(pp, self.CMD, self.cmdargs,
{ })
self.pid = self.ptransport.pid
def processData(exitcode):
# in my projects, this method opens up result files, parses results,
# moves things around, deletes tmp files, etc.
# return the result that we ran this subprocess for
return result
# Instantiate a new process manager and run it this way.
mgr = FooprocManager(args ...)
d = mgr.run(args ...)
=================
T
[View Less]