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.
21 """Base class for implementing RPC of API proxy stubs."""
36 """Base class for implementing RPC of API proxy stubs.
38 To implement a RPC to make real asynchronous API call:
40 - Override _MakeCallImpl and/or _WaitImpl to do a real asynchronous call.
47 def __init__(self
, package
=None, call
=None, request
=None, response
=None,
48 callback
=None, deadline
=None, stub
=None):
49 """Constructor for the RPC object.
51 All arguments are optional, and simply set members on the class.
52 These data members will be overriden by values passed to MakeCall.
55 package: string, the package for the call
56 call: string, the call within the package
57 request: ProtocolMessage instance, appropriate for the arguments
58 response: ProtocolMessage instance, appropriate for the response
59 callback: callable, called when call is complete
60 deadline: A double specifying the deadline for this call as the number of
61 seconds from the current time. Ignored if non-positive.
62 stub: APIProxyStub instance, used in default _WaitImpl to do real call
64 self
._exception
= None
65 self
._state
= RPC
.IDLE
66 self
._traceback
= None
68 self
.package
= package
70 self
.request
= request
71 self
.response
= response
72 self
.callback
= callback
73 self
.deadline
= deadline
75 self
.cpu_usage_mcycles
= 0
78 """Make a shallow copy of this instances attributes, excluding methods.
80 This is usually used when an RPC has been specified with some configuration
81 options and is being used as a template for multiple RPCs outside of a
82 developer's easy control.
84 if self
.state
!= RPC
.IDLE
:
85 raise AssertionError('Cannot clone a call already in progress')
87 clone
= self
.__class
__()
88 for k
, v
in self
.__dict
__.iteritems():
92 def MakeCall(self
, package
=None, call
=None, request
=None, response
=None,
93 callback
=None, deadline
=None):
94 """Makes an asynchronous (i.e. non-blocking) API call within the
95 specified package for the specified call method.
97 It will call the _MakeRealCall to do the real job.
100 Same as constructor; see __init__.
103 TypeError or AssertionError if an argument is of an invalid type.
104 AssertionError or RuntimeError is an RPC is already in use.
106 self
.callback
= callback
or self
.callback
107 self
.package
= package
or self
.package
108 self
.call
= call
or self
.call
109 self
.request
= request
or self
.request
110 self
.response
= response
or self
.response
111 self
.deadline
= deadline
or self
.deadline
113 assert self
._state
is RPC
.IDLE
, ('RPC for %s.%s has already been started' %
114 (self
.package
, self
.call
))
115 assert self
.callback
is None or callable(self
.callback
)
119 """Waits on the API call associated with this RPC."""
120 rpc_completed
= self
._WaitImpl
()
122 assert rpc_completed
, ('RPC for %s.%s was not completed, and no other '
123 'exception was raised ' % (self
.package
, self
.call
))
125 def CheckSuccess(self
):
126 """If there was an exception, raise it now.
129 Exception of the API call or the callback, if any.
131 if self
.exception
and self
._traceback
:
132 raise self
.exception
.__class
__, self
.exception
, self
._traceback
138 return self
._exception
144 def _MakeCallImpl(self
):
145 """Override this method to implement a real asynchronous call rpc."""
146 self
._state
= RPC
.RUNNING
149 """Override this method to implement a real asynchronous call rpc.
152 True if the async call was completed successfully.
156 self
.stub
.MakeSyncCall(self
.package
, self
.call
,
157 self
.request
, self
.response
)
159 _
, self
._exception
, self
._traceback
= sys
.exc_info()
161 self
._state
= RPC
.FINISHING
171 _
, self
._exception
, self
._traceback
= sys
.exc_info()
172 self
._exception
._appengine
_apiproxy
_rpc
= self