@@ -91,6 +91,7 @@ def __init__(self, loop: BaseEventLoop, host: str, port: int,
91
91
self ._shmem_mgr = SharedMemoryManager ()
92
92
self ._old_task_factory = None
93
93
self .function_metadata_result = None
94
+ self ._has_http_func = False
94
95
95
96
# Used to store metadata returns
96
97
self ._function_metadata_result = None
@@ -516,6 +517,7 @@ async def _handle__function_load_request(self, request):
516
517
async def _handle__invocation_request (self , request ):
517
518
invocation_time = datetime .utcnow ()
518
519
invoc_request = request .invocation_request
520
+ trigger_metadata = invoc_request .trigger_metadata
519
521
invocation_id = invoc_request .invocation_id
520
522
function_id = invoc_request .function_id
521
523
@@ -560,13 +562,19 @@ async def _handle__invocation_request(self, request):
560
562
pytype = pb_type_info .pytype ,
561
563
shmem_mgr = self ._shmem_mgr )
562
564
565
+ http_v2_enabled = False
563
566
if fi .trigger_metadata .get ('type' ) == HTTP_TRIGGER :
564
567
from azure .functions .extension .base import HttpV2FeatureChecker
565
568
http_v2_enabled = HttpV2FeatureChecker .http_v2_enabled ()
566
569
567
570
if http_v2_enabled :
568
571
http_request = await http_coordinator .get_http_request_async (
569
572
invocation_id )
573
+
574
+ from azure .functions .extension .base import RequestTrackerMeta
575
+ route_params = {key : item .string for key , item in trigger_metadata .items () if key not in ['Headers' , 'Query' ]}
576
+
577
+ RequestTrackerMeta .get_synchronizer ().sync_route_params (http_request , route_params )
570
578
args [fi .trigger_metadata .get ('param_name' )] = http_request
571
579
572
580
fi_context = self ._get_context (invoc_request , fi .name , fi .directory )
@@ -581,23 +589,26 @@ async def _handle__invocation_request(self, request):
581
589
for name in fi .output_types :
582
590
args [name ] = bindings .Out ()
583
591
584
- if fi .is_async :
585
- call_result = await self ._run_async_func (
586
- fi_context , fi .func , args
587
- )
588
-
589
- else :
590
- call_result = await self ._loop .run_in_executor (
591
- self ._sync_call_tp ,
592
- self ._run_sync_func ,
593
- invocation_id , fi_context , fi .func , args )
594
-
595
- if call_result is not None and not fi .has_return :
596
- raise RuntimeError (f'function { fi .name !r} without a $return '
597
- 'binding returned a non-None value' )
598
-
599
- if http_v2_enabled :
600
- http_coordinator .set_http_response (invocation_id , call_result )
592
+ call_result = None
593
+ call_error = None
594
+ try :
595
+ if fi .is_async :
596
+ call_result = await self ._run_async_func (fi_context , fi .func , args )
597
+ else :
598
+ call_result = await self ._loop .run_in_executor (
599
+ self ._sync_call_tp ,
600
+ self ._run_sync_func ,
601
+ invocation_id , fi_context , fi .func , args )
602
+
603
+ if call_result is not None and not fi .has_return :
604
+ raise RuntimeError (f'function { fi .name !r} without a $return '
605
+ 'binding returned a non-None value' )
606
+ except Exception as e :
607
+ call_error = e
608
+ raise
609
+ finally :
610
+ if http_v2_enabled :
611
+ http_coordinator .set_http_response (invocation_id , call_result if call_result is not None else call_error )
601
612
602
613
output_data = []
603
614
cache_enabled = self ._function_data_cache_enabled
@@ -753,16 +764,23 @@ async def catch_all(request: request_type): # type: ignore
753
764
invoc_id = request .headers .get (X_MS_INVOCATION_ID )
754
765
if invoc_id is None :
755
766
raise ValueError (f"Header { X_MS_INVOCATION_ID } not found" )
756
-
767
+ logger . info ( 'Received HTTP request for invocation %s' , invoc_id )
757
768
http_coordinator .set_http_request (invoc_id , request )
758
769
http_resp = await http_coordinator .await_http_response_async (invoc_id )
770
+
771
+ logger .info ('Sending HTTP response for invocation %s' , invoc_id )
772
+ # if http_resp is an python exception, raise it
773
+ if isinstance (http_resp , Exception ):
774
+ raise http_resp
775
+
759
776
return http_resp
760
777
761
778
web_server = web_server_class (LOCAL_HOST , unused_port , app )
762
779
web_server_run_task = web_server .serve ()
763
780
764
781
loop = asyncio .get_event_loop ()
765
782
loop .create_task (web_server_run_task )
783
+ logger .info ('HTTP server starting on %s:%s' , LOCAL_HOST , unused_port )
766
784
767
785
return f"http://{ LOCAL_HOST } :{ unused_port } "
768
786
@@ -779,7 +797,6 @@ def index_functions(self, function_path: str):
779
797
indexed_functions )
780
798
781
799
indexed_function_logs : List [str ] = []
782
- self ._has_http_func = False
783
800
for func in indexed_functions :
784
801
self ._has_http_func = self ._has_http_func or func .is_http_function ()
785
802
function_log = "Function Name: {}, Function Binding: {}" \
0 commit comments