Update Google App Engine to 1.2.2 in thirdparty folder.
[Melange.git] / thirdparty / google_appengine / google / appengine / api / apiproxy_rpc.py
blobd617e3b3108982638007f2ce57eb3154eee9a230
1 #!/usr/bin/env python
3 # Copyright 2007 Google Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
18 """Base class for implementing RPC of API proxy stubs."""
24 import sys
27 class RPC(object):
28 """Base class for implementing RPC of API proxy stubs.
30 To implement a RPC to make real asynchronous API call:
31 - Extend this class.
32 - Override _MakeCallImpl and/or _WaitImpl to do a real asynchronous call.
33 """
35 IDLE = 0
36 RUNNING = 1
37 FINISHING = 2
39 def __init__(self, package=None, call=None, request=None, response=None,
40 callback=None, deadline=None, stub=None):
41 """Constructor for the RPC object.
43 All arguments are optional, and simply set members on the class.
44 These data members will be overriden by values passed to MakeCall.
46 Args:
47 package: string, the package for the call
48 call: string, the call within the package
49 request: ProtocolMessage instance, appropriate for the arguments
50 response: ProtocolMessage instance, appropriate for the response
51 callback: callable, called when call is complete
52 deadline: A double specifying the deadline for this call as the number of
53 seconds from the current time. Ignored if non-positive.
54 stub: APIProxyStub instance, used in default _WaitImpl to do real call
55 """
56 self.__exception = None
57 self.__state = RPC.IDLE
58 self.__traceback = None
60 self.package = package
61 self.call = call
62 self.request = request
63 self.response = response
64 self.callback = callback
65 self.deadline = deadline
66 self.stub = stub
68 def MakeCall(self, package=None, call=None, request=None, response=None,
69 callback=None, deadline=None):
70 """Makes an asynchronous (i.e. non-blocking) API call within the
71 specified package for the specified call method.
73 It will call the _MakeRealCall to do the real job.
75 Args:
76 Same as constructor; see __init__.
78 Raises:
79 TypeError or AssertionError if an argument is of an invalid type.
80 AssertionError or RuntimeError is an RPC is already in use.
81 """
82 self.callback = callback or self.callback
83 self.package = package or self.package
84 self.call = call or self.call
85 self.request = request or self.request
86 self.response = response or self.response
87 self.deadline = deadline or self.deadline
89 assert self.__state is RPC.IDLE, ('RPC for %s.%s has already been started' %
90 (self.package, self.call))
91 assert self.callback is None or callable(self.callback)
92 self._MakeCallImpl()
94 def Wait(self):
95 """Waits on the API call associated with this RPC."""
96 assert self.__state is not RPC.IDLE, ('RPC for %s.%s has not been started' %
97 (self.package, self.call))
98 rpc_completed = self._WaitImpl()
100 assert rpc_completed, ('RPC for %s.%s was not completed, and no other ' +
101 'exception was raised ' % (self.package, self.call))
103 def CheckSuccess(self):
104 """If there was an exception, raise it now.
106 Raises:
107 Exception of the API call or the callback, if any.
109 if self.exception and self.__traceback:
110 raise self.exception.__class__, self.exception, self.__traceback
111 elif self.exception:
112 raise self.exception
114 @property
115 def exception(self):
116 return self.__exception
118 @property
119 def state(self):
120 return self.__state
122 def _MakeCallImpl(self):
123 """Override this method to implement a real asynchronous call rpc."""
124 self.__state = RPC.RUNNING
126 def _WaitImpl(self):
127 """Override this method to implement a real asynchronous call rpc.
129 Returns:
130 True if the async call was completed successfully.
132 try:
133 try:
134 self.stub.MakeSyncCall(self.package, self.call,
135 self.request, self.response)
136 except Exception, e:
137 self.__exception = e
138 finally:
139 self.__state = RPC.FINISHING
140 self.__Callback()
142 return True
144 def __Callback(self):
145 if self.callback:
146 try:
147 self.callback()
148 except:
149 exc_class, self.__exception, self.__traceback = sys.exc_info()
150 self.__exception._appengine_apiproxy_rpc = self
151 raise