from __future__ import print_function
import sys
import time

import Pyro4


if sys.version_info < (3, 0):
    input = raw_input


def asyncFunction(values):
    results = [value + 1 for value in values]
    print(">>> async batch function called, returning:", results)
    return results


uri = input("enter async server object uri: ").strip()
proxy = Pyro4.Proxy(uri)

print("\n* batch async call:")
batch = Pyro4.batch(proxy)
batch.divide(100, 5)
batch.divide(99, 9)
batch.divide(555, 2)
print("getting results...")
asyncresults = batch(asynchronous=True)  # returns immediately
print("result value available?", asyncresults.ready)  # prints False because the server is still 'busy'
print("client can do other stuff here.")
time.sleep(2)
print("such as sleeping ;-)")
time.sleep(2)
print("sleeping some more, batch takes a while")
time.sleep(2)
print("getting result values...(will block until available)")
results = asyncresults.value  # blocks until the result is available
print("resultvalues=", list(results))

print("\n* batch async call with chained function:")
batch = Pyro4.batch(proxy)
batch.divide(100, 5)
batch.divide(99, 9)
batch.divide(555, 2)
asyncresults = batch(asynchronous=True)  # returns immediately
asyncresults.then(asyncFunction) \
    .then(asyncFunction) \
    .then(asyncFunction)
print("getting result values...(will block until available)")
print("final value=", asyncresults.value)

print("\n* batch async call with exception:")
batch = Pyro4.batch(proxy)
batch.divide(1, 1)  # first call is ok
batch.divide(100, 0)  # second call will trigger a zero division error, 100//0
asyncresults = batch(asynchronous=True)  # returns immediately
print("getting result values...")
try:
    value = asyncresults.value
    print("Weird, this shouldn't succeed!?... resultvalues=", list(value))
except ZeroDivisionError as x:
    print("got exception (expected):", repr(x))

print("\n* batch async call with timeout:")
batch = Pyro4.batch(proxy)
batch.divide(100, 5)
batch.divide(99, 9)
batch.divide(555, 2)
asyncresults = batch(asynchronous=True)  # returns immediately
print("checking if ready within 2 seconds...")
ready = asyncresults.wait(2)  # wait for ready within 2 seconds but the server takes 3
print("status after wait=", ready)  # should print False
print("checking again if ready within 10 seconds...(should be ok now)")
ready = asyncresults.wait(timeout=10)  # wait 10 seconds now (but server will be done within ~8 more seconds)
print("status after wait=", ready)
print("available=", asyncresults.ready)
results = asyncresults.value
print("resultvalues=", list(results))

print("\ndone.")
