In article <11**********************@o13g2000cwo.googlegroups .com>,
Rhamphoryncus <rh****@gmail.com> wrote:
import mainloop, urllib
def get_and_save(path):
infile = waitfor urllib.urlopen(path, async=True)
outfile = waitfor open(path.split('/')[-1], async=True)
waitfor outfile.write(waitfor infile.read(async=True), async=True)
infile.close()
outfile.close()
def main():
a = get_and_save("http://python.org/pics/PyBanner021.gif")
b = get_and_save("http://python.org/pics/pythonHi.gif")
c = get_and_save("http://python.org/pics/PythonPoweredSmall.gif")
waitfor allDone(a, b, c)
if __name__ == "__main__":
mainloop.runUntil(main())
Well there you have it. I've glossed over many details but they can be
cleared up later. What I need to know now is how everybody else thinks
about it. Is this something you would use? Does it seem like the
right way to do it? And of course the all important one, can I get it
in to python core? <0.5 wink>
A while back I tossed something together to deal with the same issue
in terms of "futures" (or "promises".) Here is roughly what the above
code would look like with futures as I implemented them:
################################################## #########################
import urllib
from future import future
def get_and_save(path):
infile = future(urllib.urlopen, path)
outfile = future(open, path.split('/')[-1])
def save(infile, outfile):
outfile().write(infile().read())
infile().close()
outfile().close()
return future(save, infile, outfile)
def main():
a = get_and_save("http://python.org/pics/PyBanner021.gif")
b = get_and_save("http://python.org/pics/pythonHi.gif")
c = get_and_save("http://python.org/pics/PythonPoweredSmall.gif")
a(), b(), c()
if __name__ == "__main__":
main()
################################################## #########################
The future object initializer always returns immediately, and
the resulting "future" object can be passed around like any other
object. The __call__ method on the future object is used to get
the actual value. (I'm sure this could be avoided these days with
some sort of metaclass magic, but I haven't explored metaclasses
yet.) If the value is ready, it is returned immediately; otherwise,
the accessor's thread is blocked until it is made ready, and then
the value is returned (or the appropriate exception is raised.)
Specifying a callable (and optional parameters) in the initializer
causes resolver threads to be fired off, and the result of the
callable's evaluation in the thread becomes the future's value. If
you don't specify anything, you can arrange to resolve the value
some other way. (This is useful if the value is provided by some
asynchronous mechanism.)
This was all done using plain Python 1.5.2 in 80 lines of code,
including some blank lines and doc strings. Maybe I'll brush off
the code a bit and post it one of these days.
Gary Duzan
BBN Technologies