pull in additional changes from 2.0 branch.
[monitor.git] / monitor / Rpyc / Demo / demo-3.py
diff --git a/monitor/Rpyc/Demo/demo-3.py b/monitor/Rpyc/Demo/demo-3.py
new file mode 100644 (file)
index 0000000..220681e
--- /dev/null
@@ -0,0 +1,130 @@
+#\r
+# this is the grand finale: asynchronous proxies as super-events\r
+#\r
+from Rpyc.Factories import SocketConnection, Async\r
+from Rpyc.Utils import *\r
+\r
+c = SocketConnection("localhost")\r
+\r
+#\r
+# this is the remote int type\r
+#\r
+rint = c.modules.__builtin__.int\r
+\r
+#\r
+# and we'll wrap it in an asynchronous wrapper\r
+#\r
+rint = Async(rint)\r
+\r
+#\r
+# now it still looks like a normal proxy... but operations on it return something called\r
+# an AsyncResult -- it's an object that represents the would-be result of the operation.\r
+# it has a .is_ready property, which indicates whether or not the result is ready, and \r
+# a .result property, which holds the result of the operations. when you access the .result\r
+# property, it will block until the result is returned\r
+#\r
+a = rint("123")\r
+b = rint("metallica")\r
+print a\r
+print b.is_ready\r
+print a.result\r
+print a\r
+\r
+#\r
+# and when an exception occurs, it looks like that\r
+#\r
+try:\r
+    b.result\r
+except ValueError:\r
+    pass\r
+\r
+#\r
+# only when you access the result you get the exception, which may look weird, but hey,\r
+# it's an asynchronous world out there.\r
+#\r
+\r
+#\r
+# there's another methodology for async proxies -- on_ready callbacks. instead of \r
+# getting the async result, you can register a callback to collect it, when it arrives.\r
+#\r
+def f(res):\r
+    print "the result is",\r
+    try:\r
+        print res.result\r
+    except:\r
+        print "an exception"\r
+\r
+rint = Async(c.modules.__builtin__.int)\r
+\r
+ar = rint("123")\r
+ar.on_ready = f\r
+\r
+# this will cause an exception\r
+ar = rint("a perfect circle")\r
+ar.on_ready = f\r
+\r
+# or when you dont need to keep the async result \r
+rint("456").on_ready = f\r
+\r
+# and it's not limited to calling it. anything you do to the async proxy is asynchronous.\r
+# for example, you can also get attributes asynchronously:\r
+ar = rint.__str__\r
+\r
+#\r
+# now we'll do some other request, which will cause the results to arrive, and the callback \r
+# to be called. \r
+#\r
+print c.modules.sys\r
+\r
+############################################################################################\r
+#\r
+# this is where we get hardcore: threads and event callbacks\r
+#\r
+xxx = 0\r
+def blah():\r
+    global xxx\r
+    xxx += 1\r
+\r
+#\r
+# we'll start a thread on the server which on threadfunc (which is defined in the testmodule).\r
+# this function will call the callback we give it every second, but will ignore the result.\r
+# this practically means it's like an event -- trigger and forget. on the client side, the\r
+# callback will increment `xxx` every time it's called\r
+#\r
+c.modules.thread.start_new_thread(c.modules.Rpyc.Demo.testmodule.threadfunc, (blah,))\r
+\r
+#\r
+# we'll wait a little\r
+#\r
+import time\r
+time.sleep(5)\r
+\r
+#\r
+# and do some operation, which, along with it, will pull all incoming requests\r
+#\r
+print c.modules.sys\r
+print xxx\r
+\r
+#\r
+# and we can start a thread of our own to pull the requests in the background\r
+#\r
+import thread\r
+worker_running = True\r
+\r
+def worker(conn):\r
+    while worker_running:\r
+        conn.serve()\r
+\r
+thread.start_new_thread(worker, (c,))\r
+\r
+time.sleep(5)\r
+worker_running = False\r
+\r
+print xxx\r
+print "goodbye"\r
+\r
+#\r
+# L33TN3SS\r
+#\r
+\r
+\r