220681e40e7ab25040ff66a4b78a2dcae4c9246c
[monitor.git] / Rpyc / Demo / demo-3.py
1 #\r
2 # this is the grand finale: asynchronous proxies as super-events\r
3 #\r
4 from Rpyc.Factories import SocketConnection, Async\r
5 from Rpyc.Utils import *\r
6 \r
7 c = SocketConnection("localhost")\r
8 \r
9 #\r
10 # this is the remote int type\r
11 #\r
12 rint = c.modules.__builtin__.int\r
13 \r
14 #\r
15 # and we'll wrap it in an asynchronous wrapper\r
16 #\r
17 rint = Async(rint)\r
18 \r
19 #\r
20 # now it still looks like a normal proxy... but operations on it return something called\r
21 # an AsyncResult -- it's an object that represents the would-be result of the operation.\r
22 # it has a .is_ready property, which indicates whether or not the result is ready, and \r
23 # a .result property, which holds the result of the operations. when you access the .result\r
24 # property, it will block until the result is returned\r
25 #\r
26 a = rint("123")\r
27 b = rint("metallica")\r
28 print a\r
29 print b.is_ready\r
30 print a.result\r
31 print a\r
32 \r
33 #\r
34 # and when an exception occurs, it looks like that\r
35 #\r
36 try:\r
37     b.result\r
38 except ValueError:\r
39     pass\r
40 \r
41 #\r
42 # only when you access the result you get the exception, which may look weird, but hey,\r
43 # it's an asynchronous world out there.\r
44 #\r
45 \r
46 #\r
47 # there's another methodology for async proxies -- on_ready callbacks. instead of \r
48 # getting the async result, you can register a callback to collect it, when it arrives.\r
49 #\r
50 def f(res):\r
51     print "the result is",\r
52     try:\r
53         print res.result\r
54     except:\r
55         print "an exception"\r
56 \r
57 rint = Async(c.modules.__builtin__.int)\r
58 \r
59 ar = rint("123")\r
60 ar.on_ready = f\r
61 \r
62 # this will cause an exception\r
63 ar = rint("a perfect circle")\r
64 ar.on_ready = f\r
65 \r
66 # or when you dont need to keep the async result \r
67 rint("456").on_ready = f\r
68 \r
69 # and it's not limited to calling it. anything you do to the async proxy is asynchronous.\r
70 # for example, you can also get attributes asynchronously:\r
71 ar = rint.__str__\r
72 \r
73 #\r
74 # now we'll do some other request, which will cause the results to arrive, and the callback \r
75 # to be called. \r
76 #\r
77 print c.modules.sys\r
78 \r
79 ############################################################################################\r
80 #\r
81 # this is where we get hardcore: threads and event callbacks\r
82 #\r
83 xxx = 0\r
84 def blah():\r
85     global xxx\r
86     xxx += 1\r
87 \r
88 #\r
89 # we'll start a thread on the server which on threadfunc (which is defined in the testmodule).\r
90 # this function will call the callback we give it every second, but will ignore the result.\r
91 # this practically means it's like an event -- trigger and forget. on the client side, the\r
92 # callback will increment `xxx` every time it's called\r
93 #\r
94 c.modules.thread.start_new_thread(c.modules.Rpyc.Demo.testmodule.threadfunc, (blah,))\r
95 \r
96 #\r
97 # we'll wait a little\r
98 #\r
99 import time\r
100 time.sleep(5)\r
101 \r
102 #\r
103 # and do some operation, which, along with it, will pull all incoming requests\r
104 #\r
105 print c.modules.sys\r
106 print xxx\r
107 \r
108 #\r
109 # and we can start a thread of our own to pull the requests in the background\r
110 #\r
111 import thread\r
112 worker_running = True\r
113 \r
114 def worker(conn):\r
115     while worker_running:\r
116         conn.serve()\r
117 \r
118 thread.start_new_thread(worker, (c,))\r
119 \r
120 time.sleep(5)\r
121 worker_running = False\r
122 \r
123 print xxx\r
124 print "goodbye"\r
125 \r
126 #\r
127 # L33TN3SS\r
128 #\r
129 \r
130 \r