7
7
8
8
from azure_functions_worker .constants import X_MS_INVOCATION_ID , \
9
9
BASE_EXT_SUPPORTED_PY_MINOR_VERSION , PYTHON_ENABLE_INIT_INDEXING
10
+ from azure_functions_worker .exceptions import MissingHeaderError , \
11
+ HttpServerInitError
10
12
from azure_functions_worker .logging import logger
11
13
from azure_functions_worker .utils .common import is_envvar_false
12
14
@@ -113,25 +115,24 @@ def set_http_request(self, invoc_id, http_request):
113
115
114
116
def set_http_response (self , invoc_id , http_response ):
115
117
if invoc_id not in self ._context_references :
116
- raise Exception ("No context reference found for invocation "
117
- f" { invoc_id } " )
118
+ raise KeyError ("No context reference found for invocation %s "
119
+ % invoc_id )
118
120
context_ref = self ._context_references .get (invoc_id )
119
121
context_ref .http_response = http_response
120
122
121
123
async def get_http_request_async (self , invoc_id ):
122
124
if invoc_id not in self ._context_references :
123
125
self ._context_references [invoc_id ] = AsyncContextReference ()
124
126
125
- await asyncio .sleep (0 )
126
127
await self ._context_references .get (
127
128
invoc_id ).http_request_available_event .wait ()
128
129
return self ._pop_http_request (invoc_id )
129
130
130
131
async def await_http_response_async (self , invoc_id ):
131
132
if invoc_id not in self ._context_references :
132
- raise Exception ("No context reference found for invocation "
133
- f" { invoc_id } " )
134
- await asyncio . sleep ( 0 )
133
+ raise KeyError ("No context reference found for invocation %s "
134
+ % invoc_id )
135
+
135
136
await self ._context_references .get (
136
137
invoc_id ).http_response_available_event .wait ()
137
138
return self ._pop_http_response (invoc_id )
@@ -143,7 +144,7 @@ def _pop_http_request(self, invoc_id):
143
144
context_ref .http_request = None
144
145
return request
145
146
146
- raise ValueError (f "No http request found for invocation { invoc_id } " )
147
+ raise ValueError ("No http request found for invocation %s" % invoc_id )
147
148
148
149
def _pop_http_response (self , invoc_id ):
149
150
context_ref = self ._context_references .get (invoc_id )
@@ -152,7 +153,7 @@ def _pop_http_response(self, invoc_id):
152
153
context_ref .http_response = None
153
154
return response
154
155
155
- raise ValueError (f "No http response found for invocation { invoc_id } " )
156
+ raise ValueError ("No http response found for invocation %s" % invoc_id )
156
157
157
158
158
159
def get_unused_tcp_port ():
@@ -169,44 +170,50 @@ def get_unused_tcp_port():
169
170
170
171
171
172
def initialize_http_server (host_addr , ** kwargs ):
172
- ext_base = HttpV2Registry .ext_base ()
173
- web_extension_mod_name = ext_base .ModuleTrackerMeta .get_module ()
174
- extension_module = importlib .import_module (web_extension_mod_name )
175
- web_app_class = extension_module .WebApp
176
- web_server_class = extension_module .WebServer
177
-
178
- unused_port = get_unused_tcp_port ()
179
-
180
- app = web_app_class ()
181
- request_type = ext_base .RequestTrackerMeta .get_request_type ()
182
-
183
- @app .route
184
- async def catch_all (request : request_type ): # type: ignore
185
- invoc_id = request .headers .get (X_MS_INVOCATION_ID )
186
- if invoc_id is None :
187
- raise ValueError (f"Header { X_MS_INVOCATION_ID } not found" )
188
- logger .info ('Received HTTP request for invocation %s' , invoc_id )
189
- http_coordinator .set_http_request (invoc_id , request )
190
- http_resp = \
191
- await http_coordinator .await_http_response_async (invoc_id )
192
-
193
- logger .info ('Sending HTTP response for invocation %s' , invoc_id )
194
- # if http_resp is an python exception, raise it
195
- if isinstance (http_resp , Exception ):
196
- raise http_resp
197
-
198
- return http_resp
199
-
200
- web_server = web_server_class (host_addr , unused_port , app )
201
- web_server_run_task = web_server .serve ()
202
-
203
- loop = asyncio .get_event_loop ()
204
- loop .create_task (web_server_run_task )
205
-
206
- web_server_address = f"http://{ host_addr } :{ unused_port } "
207
- logger .info ('HTTP server starting on %s' , web_server_address )
208
-
209
- return web_server_address
173
+ try :
174
+ ext_base = HttpV2Registry .ext_base ()
175
+ web_extension_mod_name = ext_base .ModuleTrackerMeta .get_module ()
176
+ extension_module = importlib .import_module (web_extension_mod_name )
177
+ web_app_class = extension_module .WebApp
178
+ web_server_class = extension_module .WebServer
179
+
180
+ unused_port = get_unused_tcp_port ()
181
+
182
+ app = web_app_class ()
183
+ request_type = ext_base .RequestTrackerMeta .get_request_type ()
184
+
185
+ @app .route
186
+ async def catch_all (request : request_type ): # type: ignore
187
+ invoc_id = request .headers .get (X_MS_INVOCATION_ID )
188
+ if invoc_id is None :
189
+ raise MissingHeaderError ("Header %s not found" %
190
+ X_MS_INVOCATION_ID )
191
+ logger .info ('Received HTTP request for invocation %s' , invoc_id )
192
+ http_coordinator .set_http_request (invoc_id , request )
193
+ http_resp = \
194
+ await http_coordinator .await_http_response_async (invoc_id )
195
+
196
+ logger .info ('Sending HTTP response for invocation %s' , invoc_id )
197
+ # if http_resp is an python exception, raise it
198
+ if isinstance (http_resp , Exception ):
199
+ raise http_resp
200
+
201
+ return http_resp
202
+
203
+ web_server = web_server_class (host_addr , unused_port , app )
204
+ web_server_run_task = web_server .serve ()
205
+
206
+ loop = asyncio .get_event_loop ()
207
+ loop .create_task (web_server_run_task )
208
+
209
+ web_server_address = f"http://{ host_addr } :{ unused_port } "
210
+ logger .info ('HTTP server starting on %s' , web_server_address )
211
+
212
+ return web_server_address
213
+
214
+ except Exception as e :
215
+ raise HttpServerInitError ("Error initializing HTTP server: %s" % e ) \
216
+ from e
210
217
211
218
212
219
async def sync_http_request (http_request , invoc_request ):
0 commit comments