Skip to content

Commit 1d3bc48

Browse files
authored
Merge branch 'dev' into release/test-mac-m1
2 parents 123cc09 + 832d261 commit 1d3bc48

File tree

7 files changed

+217
-100
lines changed

7 files changed

+217
-100
lines changed

azure_functions_worker/dispatcher.py

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -312,30 +312,7 @@ async def _handle__functions_metadata_request(self, request):
312312
status=protos.StatusResult.Success)))
313313

314314
try:
315-
indexed_functions = loader.index_function_app(function_path)
316-
logger.info('Indexed function app and found %s functions',
317-
len(indexed_functions))
318-
319-
fx_metadata_results = []
320-
if indexed_functions:
321-
indexed_function_logs: List[str] = []
322-
for func in indexed_functions:
323-
function_log = "Function Name: {}, Function Binding: {}" \
324-
.format(func.get_function_name(),
325-
[(binding.type, binding.name) for binding in
326-
func.get_bindings()])
327-
indexed_function_logs.append(function_log)
328-
329-
logger.info(
330-
'Successfully processed FunctionMetadataRequest for '
331-
'functions: %s', " ".join(indexed_function_logs))
332-
333-
fx_metadata_results = loader.process_indexed_function(
334-
self._functions,
335-
indexed_functions)
336-
else:
337-
logger.warning("No functions indexed. Please refer to "
338-
"aka.ms/pythonprogrammingmodel for more info.")
315+
fx_metadata_results = self.index_functions(function_path)
339316

340317
return protos.StreamingMessage(
341318
request_id=request.request_id,
@@ -355,33 +332,48 @@ async def _handle__functions_metadata_request(self, request):
355332
async def _handle__function_load_request(self, request):
356333
func_request = request.function_load_request
357334
function_id = func_request.function_id
358-
function_name = func_request.metadata.name
335+
function_metadata = func_request.metadata
336+
function_name = function_metadata.name
337+
function_path = os.path.join(function_metadata.directory,
338+
SCRIPT_FILE_NAME)
359339

360340
logger.info(
361341
'Received WorkerLoadRequest, request ID %s, function_id: %s,'
362342
'function_name: %s,', self.request_id, function_id, function_name)
363343

364344
try:
365345
if not self._functions.get_function(function_id):
366-
func = loader.load_function(
367-
func_request.metadata.name,
368-
func_request.metadata.directory,
369-
func_request.metadata.script_file,
370-
func_request.metadata.entry_point)
371-
372-
self._functions.add_function(
373-
function_id, func, func_request.metadata)
374-
375-
ExtensionManager.function_load_extension(
376-
function_name,
377-
func_request.metadata.directory
378-
)
379-
380-
logger.info('Successfully processed FunctionLoadRequest, '
381-
'request ID: %s, '
382-
'function ID: %s,'
383-
'function Name: %s', self.request_id, function_id,
384-
function_name)
346+
if function_metadata.properties.get("worker_indexed", False) \
347+
or os.path.exists(function_path):
348+
# This is for the second worker and above where the worker
349+
# indexing is enabled and load request is called without
350+
# calling the metadata request. In this case we index the
351+
# function and update the workers registry
352+
logger.info(f"Indexing function {function_name} in the "
353+
f"load request")
354+
_ = self.index_functions(function_path)
355+
else:
356+
# legacy function
357+
func = loader.load_function(
358+
func_request.metadata.name,
359+
func_request.metadata.directory,
360+
func_request.metadata.script_file,
361+
func_request.metadata.entry_point)
362+
363+
self._functions.add_function(
364+
function_id, func, func_request.metadata)
365+
366+
ExtensionManager.function_load_extension(
367+
function_name,
368+
func_request.metadata.directory
369+
)
370+
371+
logger.info('Successfully processed FunctionLoadRequest, '
372+
'request ID: %s, '
373+
'function ID: %s,'
374+
'function Name: %s', self.request_id,
375+
function_id,
376+
function_name)
385377

386378
return protos.StreamingMessage(
387379
request_id=self.request_id,
@@ -577,6 +569,30 @@ async def _handle__function_environment_reload_request(self, request):
577569
request_id=self.request_id,
578570
function_environment_reload_response=failure_response)
579571

572+
def index_functions(self, function_path: str):
573+
indexed_functions = loader.index_function_app(function_path)
574+
logger.info('Indexed function app and found %s functions',
575+
len(indexed_functions))
576+
577+
if indexed_functions:
578+
indexed_function_logs: List[str] = []
579+
for func in indexed_functions:
580+
function_log = "Function Name: {}, Function Binding: {}" \
581+
.format(func.get_function_name(),
582+
[(binding.type, binding.name) for binding in
583+
func.get_bindings()])
584+
indexed_function_logs.append(function_log)
585+
586+
logger.info(
587+
'Successfully processed FunctionMetadataRequest for '
588+
'functions: %s', " ".join(indexed_function_logs))
589+
590+
fx_metadata_results = loader.process_indexed_function(
591+
self._functions,
592+
indexed_functions)
593+
594+
return fx_metadata_results
595+
580596
async def _handle__close_shared_memory_resources_request(self, request):
581597
"""
582598
Frees any memory maps that were produced as output for a given

azure_functions_worker/functions.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import operator
55
import pathlib
66
import typing
7+
import uuid
78

89
from . import bindings as bindings_utils
910
from . import protos
@@ -21,6 +22,7 @@ class FunctionInfo(typing.NamedTuple):
2122

2223
name: str
2324
directory: str
25+
function_id: str
2426
requires_context: bool
2527
is_async: bool
2628
has_return: bool
@@ -311,6 +313,7 @@ def add_func_to_registry_and_return_funcinfo(self, function,
311313
func=function,
312314
name=function_name,
313315
directory=directory,
316+
function_id=function_id,
314317
requires_context=requires_context,
315318
is_async=inspect.iscoroutinefunction(function),
316319
has_return=has_explicit_return or has_implicit_return,
@@ -371,11 +374,12 @@ def add_function(self, function_id: str,
371374
input_types,
372375
output_types, return_type)
373376

374-
def add_indexed_function(self, function_id: str,
375-
function):
377+
def add_indexed_function(self, function):
376378
func = function.get_user_function()
377379
func_name = function.get_function_name()
378380
func_type = function.http_type
381+
function_id = str(uuid.uuid5(namespace=uuid.NAMESPACE_OID,
382+
name=func_name))
379383
return_binding_name: typing.Optional[str] = None
380384
has_explicit_return = False
381385
has_implicit_return = False

azure_functions_worker/loader.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import os.path
99
import pathlib
1010
import sys
11-
import uuid
1211
from os import PathLike, fspath
1312
from typing import Optional, Dict
1413

@@ -65,24 +64,23 @@ def process_indexed_function(functions_registry: functions.Registry,
6564
indexed_functions):
6665
fx_metadata_results = []
6766
for indexed_function in indexed_functions:
68-
function_id = str(uuid.uuid4())
6967
function_info = functions_registry.add_indexed_function(
70-
function_id,
7168
function=indexed_function)
7269

7370
binding_protos = build_binding_protos(indexed_function)
7471

7572
function_metadata = protos.RpcFunctionMetadata(
7673
name=function_info.name,
77-
function_id=function_id,
74+
function_id=function_info.function_id,
7875
managed_dependency_enabled=False, # only enabled for PowerShell
7976
directory=function_info.directory,
8077
script_file=indexed_function.function_script_file,
8178
entry_point=function_info.name,
8279
is_proxy=False, # not supported in V4
8380
language=PYTHON_LANGUAGE_RUNTIME,
8481
bindings=binding_protos,
85-
raw_bindings=indexed_function.get_raw_bindings())
82+
raw_bindings=indexed_function.get_raw_bindings(),
83+
properties={"worker_indexed": "True"})
8684

8785
fx_metadata_results.append(function_metadata)
8886

0 commit comments

Comments
 (0)