Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: configuration file #1440

Draft
wants to merge 41 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
5a85b8f
config manager class
hallvictoria Oct 19, 2023
23e2dda
basic working prototype
hallvictoria Jan 18, 2024
078a305
basic fully working prototype
hallvictoria Jan 18, 2024
bb70497
refactor common to config_manager
hallvictoria Jan 18, 2024
a3e0af1
combine os env and config file
hallvictoria Feb 6, 2024
347b900
yaml dep
hallvictoria Feb 6, 2024
225801b
install pyyaml
hallvictoria Feb 6, 2024
330b06b
pyyaml in setup
hallvictoria Feb 6, 2024
9cb58bf
read from json
hallvictoria Feb 20, 2024
06ebd25
merge with dev
hallvictoria Feb 20, 2024
409c810
some dependency and utilities tests
hallvictoria Feb 28, 2024
3fb7db1
Merge branch 'dev' of https://github.com/Azure/azure-functions-python…
Mar 6, 2024
f653191
test_dispatcher starting changes
Mar 6, 2024
cfe38ca
unit tests + lint
Mar 6, 2024
b77d1c7
filename, db log error
Mar 6, 2024
495a2de
db logging unit test
Mar 6, 2024
ca03855
lint
Mar 6, 2024
de9d40d
dispatcher test
Mar 6, 2024
e975404
weird merge
Mar 6, 2024
5bb7d5b
merge with dev
hallvictoria Aug 26, 2024
3ff5058
lint, test refactor, import ref fixes
hallvictoria Aug 26, 2024
b1e7511
merge fixes
hallvictoria Aug 26, 2024
e85a14c
fixed config is not none
Aug 30, 2024
137357e
Merge branch 'dev' into hallvictoria/config_file
hallvictoria Aug 30, 2024
9250771
local logging (revert)
Aug 30, 2024
8e34719
merge
Sep 3, 2024
2f20771
unit test fixes
Sep 3, 2024
210f5c4
refactor all keys to be upper case
Sep 4, 2024
033c480
unit test fixes
Sep 5, 2024
22264c3
fix unit tests
Sep 5, 2024
83d83fc
fix unit tests
Sep 5, 2024
e5ccc99
merge
Sep 13, 2024
bf8e509
initial refactoring to config manager class
Sep 16, 2024
bcf434b
reference bug fix
Sep 16, 2024
244ba61
refactoring for env var reading
Sep 17, 2024
88ef536
test fixes
Sep 17, 2024
af36a6e
formatting fixes
Sep 17, 2024
1ce6f51
formatting fixes
Sep 18, 2024
8834535
Merge branch 'dev' into hallvictoria/config_file
hallvictoria Sep 19, 2024
193282c
formatting fixes
Sep 19, 2024
c9edec2
Merge branch 'hallvictoria/config_file' of https://github.com/Azure/a…
Sep 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys

from ...constants import FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED
from ...utils.common import is_envvar_true
from ...utils.config_manager import config_manager
from .file_accessor import DummyFileAccessor
from .file_accessor_unix import FileAccessorUnix
from .file_accessor_windows import FileAccessorWindows
Expand All @@ -18,7 +18,7 @@ class FileAccessorFactory:
"""
@staticmethod
def create_file_accessor():
if sys.platform == "darwin" and not is_envvar_true(
if sys.platform == "darwin" and not config_manager.is_envvar_true(
FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED):
return DummyFileAccessor()
elif os.name == 'nt':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from azure_functions_worker import constants

from ...logging import logger
from ...utils.common import get_app_setting
from ...utils.config_manager import config_manager
from .file_accessor import FileAccessor
from .shared_memory_constants import SharedMemoryConstants as consts
from .shared_memory_exception import SharedMemoryException
Expand Down Expand Up @@ -95,7 +95,7 @@ def _get_allowed_mem_map_dirs(self) -> List[str]:
Otherwise, the default value will be used.
"""
setting = constants.UNIX_SHARED_MEMORY_DIRECTORIES
allowed_mem_map_dirs_str = get_app_setting(setting)
allowed_mem_map_dirs_str = config_manager.get_app_setting(setting)
if allowed_mem_map_dirs_str is None:
allowed_mem_map_dirs = consts.UNIX_TEMP_DIRS
logger.info(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from ...constants import FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED
from ...logging import logger
from ...utils.common import is_envvar_true
from ...utils.config_manager import config_manager
from ..datumdef import Datum
from .file_accessor_factory import FileAccessorFactory
from .shared_memory_constants import SharedMemoryConstants as consts
Expand Down Expand Up @@ -55,7 +55,7 @@ def is_enabled(self) -> bool:
Whether supported types should be transferred between functions host and
the worker using shared memory.
"""
return is_envvar_true(
return config_manager.is_envvar_true(
FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED)

def is_supported(self, datum: Datum) -> bool:
Expand Down
77 changes: 44 additions & 33 deletions azure_functions_worker/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
PYTHON_ENABLE_DEBUG_LOGGING,
PYTHON_ENABLE_INIT_INDEXING,
PYTHON_ENABLE_OPENTELEMETRY,
PYTHON_ENABLE_OPENTELEMETRY_DEFAULT,
PYTHON_LANGUAGE_RUNTIME,
PYTHON_ROLLBACK_CWD_PATH,
PYTHON_SCRIPT_FILE_NAME,
Expand Down Expand Up @@ -60,7 +59,8 @@
logger,
)
from .utils.app_setting_manager import get_python_appsetting_state
from .utils.common import get_app_setting, is_envvar_true, validate_script_file_name
from .utils.common import validate_script_file_name
from .utils.config_manager import config_manager
from .utils.dependency import DependencyManager
from .utils.tracing import marshall_exception_trace
from .utils.wrappers import disable_feature_by
Expand Down Expand Up @@ -113,6 +113,7 @@ def __init__(self, loop: BaseEventLoop, host: str, port: int,
# For 3.[6|7|8] The default value is 1.
# For 3.9, we don't set this value by default but we honor incoming
# the app setting.
config_manager.read_environment_variables()
self._sync_call_tp: concurrent.futures.Executor = (
self._create_sync_call_tp(self._get_sync_tp_max_workers())
)
Expand Down Expand Up @@ -188,7 +189,7 @@ async def dispatch_forever(self): # sourcery skip: swap-if-expression
logging_handler = AsyncLoggingHandler()
root_logger = logging.getLogger()

log_level = logging.INFO if not is_envvar_true(
log_level = logging.INFO if not config_manager.is_envvar_true(
PYTHON_ENABLE_DEBUG_LOGGING) else logging.DEBUG

root_logger.setLevel(log_level)
Expand Down Expand Up @@ -314,10 +315,10 @@ def initialize_azure_monitor(self):
# Connection string can be explicitly specified in Appsetting
# If not set, defaults to env var
# APPLICATIONINSIGHTS_CONNECTION_STRING
connection_string=get_app_setting(
connection_string=config_manager.get_app_setting(
setting=APPLICATIONINSIGHTS_CONNECTION_STRING
),
logger_name=get_app_setting(
logger_name=config_manager.get_app_setting(
setting=PYTHON_AZURE_MONITOR_LOGGER_NAME,
default_value=PYTHON_AZURE_MONITOR_LOGGER_NAME_DEFAULT
),
Expand Down Expand Up @@ -354,20 +355,24 @@ def update_opentelemetry_status(self):
)

async def _handle__worker_init_request(self, request):
logger.info('Received WorkerInitRequest, '
'python version %s, '
'worker version %s, '
'request ID %s. '
'App Settings state: %s. '
'To enable debug level logging, please refer to '
'https://aka.ms/python-enable-debug-logging',
sys.version,
VERSION,
self.request_id,
get_python_appsetting_state()
)

worker_init_request = request.worker_init_request
config_manager.set_config(
os.path.join(worker_init_request.function_app_directory, 'az-config.json')
)
logger.info(
'Received WorkerInitRequest, '
'python version %s, '
'worker version %s, '
'request ID %s. '
'App Settings state: %s. '
'To enable debug level logging, please refer to '
'https://aka.ms/python-enable-debug-logging',
sys.version,
VERSION,
self.request_id,
get_python_appsetting_state(),
)

host_capabilities = worker_init_request.capabilities
if constants.FUNCTION_DATA_CACHE in host_capabilities:
val = host_capabilities[constants.FUNCTION_DATA_CACHE]
Expand All @@ -381,8 +386,7 @@ async def _handle__worker_init_request(self, request):
constants.RPC_HTTP_TRIGGER_METADATA_REMOVED: _TRUE,
constants.SHARED_MEMORY_DATA_TRANSFER: _TRUE,
}
if get_app_setting(setting=PYTHON_ENABLE_OPENTELEMETRY,
default_value=PYTHON_ENABLE_OPENTELEMETRY_DEFAULT):
if config_manager.is_envvar_true(PYTHON_ENABLE_OPENTELEMETRY):
self.initialize_azure_monitor()

if self._azure_monitor_available:
Expand All @@ -398,7 +402,7 @@ async def _handle__worker_init_request(self, request):
# dictionary which will be later used in the invocation request
bindings.load_binding_registry()

if is_envvar_true(PYTHON_ENABLE_INIT_INDEXING):
if config_manager.is_envvar_true(PYTHON_ENABLE_INIT_INDEXING):
try:
self.load_function_metadata(
worker_init_request.function_app_directory,
Expand Down Expand Up @@ -436,7 +440,7 @@ def load_function_metadata(self, function_app_directory, caller_info):
directory and save the results in function_metadata_result or
function_metadata_exception in case of an exception.
"""
script_file_name = get_app_setting(
script_file_name = config_manager.get_app_setting(
setting=PYTHON_SCRIPT_FILE_NAME,
default_value=f'{PYTHON_SCRIPT_FILE_NAME_DEFAULT}')

Expand All @@ -459,7 +463,7 @@ async def _handle__functions_metadata_request(self, request):
metadata_request = request.functions_metadata_request
function_app_directory = metadata_request.function_app_directory

script_file_name = get_app_setting(
script_file_name = config_manager.get_app_setting(
setting=PYTHON_SCRIPT_FILE_NAME,
default_value=f'{PYTHON_SCRIPT_FILE_NAME_DEFAULT}')
function_path = os.path.join(function_app_directory,
Expand All @@ -468,9 +472,11 @@ async def _handle__functions_metadata_request(self, request):
logger.info(
'Received WorkerMetadataRequest, request ID %s, '
'function_path: %s',
self.request_id, function_path)
self.request_id,
function_path,
)

if not is_envvar_true(PYTHON_ENABLE_INIT_INDEXING):
if not config_manager.is_envvar_true(PYTHON_ENABLE_INIT_INDEXING):
try:
self.load_function_metadata(
function_app_directory,
Expand Down Expand Up @@ -757,17 +763,23 @@ async def _handle__function_environment_reload_request(self, request):

# Reload environment variables
os.environ.clear()
config_manager.clear_config()
env_vars = func_env_reload_request.environment_variables
for var in env_vars:
os.environ[var] = env_vars[var]
config_manager.set_config(
os.path.join(
func_env_reload_request.function_app_directory, 'az-config.json'
)
)

# Apply PYTHON_THREADPOOL_THREAD_COUNT
self._stop_sync_call_tp()
self._sync_call_tp = (
self._create_sync_call_tp(self._get_sync_tp_max_workers())
)

if is_envvar_true(PYTHON_ENABLE_DEBUG_LOGGING):
if config_manager.is_envvar_true(PYTHON_ENABLE_DEBUG_LOGGING):
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)

Expand All @@ -779,16 +791,14 @@ async def _handle__function_environment_reload_request(self, request):
bindings.load_binding_registry()

capabilities = {}
if get_app_setting(
setting=PYTHON_ENABLE_OPENTELEMETRY,
default_value=PYTHON_ENABLE_OPENTELEMETRY_DEFAULT):
if config_manager.is_envvar_true(PYTHON_ENABLE_OPENTELEMETRY):
self.initialize_azure_monitor()

if self._azure_monitor_available:
capabilities[constants.WORKER_OPEN_TELEMETRY_ENABLED] = (
_TRUE)

if is_envvar_true(PYTHON_ENABLE_INIT_INDEXING):
if config_manager.is_envvar_true(PYTHON_ENABLE_INIT_INDEXING):
try:
self.load_function_metadata(
directory,
Expand Down Expand Up @@ -969,9 +979,10 @@ def tp_max_workers_validator(value: str) -> bool:
default_value = None if sys.version_info.minor >= 9 \
else f'{PYTHON_THREADPOOL_THREAD_COUNT_DEFAULT}'

max_workers = get_app_setting(setting=PYTHON_THREADPOOL_THREAD_COUNT,
default_value=default_value,
validator=tp_max_workers_validator)
max_workers = config_manager.get_app_setting(
setting=PYTHON_THREADPOOL_THREAD_COUNT,
default_value=default_value,
validator=tp_max_workers_validator)

if sys.version_info.minor <= 7:
max_workers = min(int(max_workers),
Expand Down
4 changes: 2 additions & 2 deletions azure_functions_worker/http_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
X_MS_INVOCATION_ID,
)
from azure_functions_worker.logging import logger
from azure_functions_worker.utils.common import is_envvar_false
from azure_functions_worker.utils.config_manager import config_manager


# Http V2 Exceptions
Expand Down Expand Up @@ -280,7 +280,7 @@ def ext_base(cls):
@classmethod
def _check_http_v2_enabled(cls):
if sys.version_info.minor < BASE_EXT_SUPPORTED_PY_MINOR_VERSION or \
is_envvar_false(PYTHON_ENABLE_INIT_INDEXING):
config_manager.is_envvar_false(PYTHON_ENABLE_INIT_INDEXING):
return False

import azurefunctions.extensions.base as ext_base
Expand Down
4 changes: 2 additions & 2 deletions azure_functions_worker/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
RETRY_POLICY,
)
from .logging import logger
from .utils.common import get_app_setting
from .utils.config_manager import config_manager
from .utils.wrappers import attach_message_to_exception

_AZURE_NAMESPACE = '__app__'
Expand Down Expand Up @@ -255,7 +255,7 @@ def index_function_app(function_path: str):
f"level function app instances are defined.")

if not app:
script_file_name = get_app_setting(
script_file_name = config_manager.get_app_setting(
setting=PYTHON_SCRIPT_FILE_NAME,
default_value=f'{PYTHON_SCRIPT_FILE_NAME_DEFAULT}')
raise ValueError("Could not find top level function app instances in "
Expand Down
4 changes: 2 additions & 2 deletions azure_functions_worker/utils/app_setting_manager.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
import os
import sys

from .config_manager import config_manager
from ..constants import (
FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED,
PYTHON_ENABLE_DEBUG_LOGGING,
Expand All @@ -19,7 +19,7 @@


def get_python_appsetting_state():
current_vars = os.environ.copy()
current_vars = config_manager.get_config()
python_specific_settings = \
[PYTHON_ROLLBACK_CWD_PATH,
PYTHON_THREADPOOL_THREAD_COUNT,
Expand Down
Loading
Loading