diff --git a/azure_functions_worker/bindings/meta.py b/azure_functions_worker/bindings/meta.py index 5d84a06f5..b179331f5 100644 --- a/azure_functions_worker/bindings/meta.py +++ b/azure_functions_worker/bindings/meta.py @@ -22,7 +22,6 @@ BINDING_REGISTRY = None DEFERRED_BINDING_REGISTRY = None -deferred_bindings_cache = {} def _check_http_input_type_annotation(bind_name: str, pytype: type, @@ -285,48 +284,8 @@ def deferred_bindings_decode(binding: typing.Any, datum: typing.Any, metadata: typing.Any, function_name: str): - """ - This cache holds deferred binding types (ie. BlobClient, ContainerClient) - That have already been created, so that the worker can reuse the - Previously created type without creating a new one. - - For async types, the function_name is needed as a key to differentiate. - This prevents a known SDK issue where reusing a client across functions - can lose the session context and cause an error. - - The cache key is based on: param name, type, resource, function_name - If cache is empty or key doesn't exist, deferred_binding_type is None - """ - global deferred_bindings_cache - - # Only applies to Event Hub and Service Bus - cannot cache - # These types will always produce different content and are not clients - if (datum.type == "collection_model_binding_data" - or datum.value.source == "AzureEventHubsEventData" - or datum.value.source == "AzureServiceBusReceivedMessage"): - return binding.decode(datum, - trigger_metadata=metadata, - pytype=pytype) - - if deferred_bindings_cache.get((pb.name, - pytype, - datum.value.content, - function_name), None) is not None: - return deferred_bindings_cache.get((pb.name, - pytype, - datum.value.content, - function_name)) - else: - deferred_binding_type = binding.decode(datum, - trigger_metadata=metadata, - pytype=pytype) - - deferred_bindings_cache[(pb.name, - pytype, - datum.value.content, - function_name)] = deferred_binding_type - return deferred_binding_type + return binding.decode(datum, trigger_metadata=metadata, pytype=pytype) def check_deferred_bindings_enabled(param_anno: type, diff --git a/tests/extension_tests/deferred_bindings_tests/deferred_bindings_blob_functions/function_app.py b/tests/extension_tests/deferred_bindings_tests/deferred_bindings_blob_functions/function_app.py index 075d8a78a..087df4be9 100644 --- a/tests/extension_tests/deferred_bindings_tests/deferred_bindings_blob_functions/function_app.py +++ b/tests/extension_tests/deferred_bindings_tests/deferred_bindings_blob_functions/function_app.py @@ -249,41 +249,6 @@ def put_blob_bytes(req: func.HttpRequest, file: func.Out[bytes]) -> str: return 'OK' -@app.function_name(name="blob_cache") -@app.blob_input(arg_name="cachedClient", - path="python-worker-tests/test-blobclient-triggered.txt", - connection="AzureWebJobsStorage") -@app.route(route="blob_cache") -def blob_cache(req: func.HttpRequest, - cachedClient: blob.BlobClient) -> str: - return func.HttpResponse(repr(cachedClient)) - - -@app.function_name(name="blob_cache2") -@app.blob_input(arg_name="cachedClient", - path="python-worker-tests/test-blobclient-triggered.txt", - connection="AzureWebJobsStorage") -@app.route(route="blob_cache2") -def blob_cache2(req: func.HttpRequest, - cachedClient: blob.BlobClient) -> func.HttpResponse: - return func.HttpResponse(repr(cachedClient)) - - -@app.function_name(name="blob_cache3") -@app.blob_input(arg_name="cachedClient", - path="python-worker-tests/test-blobclient-triggered.txt", - connection="AzureWebJobsStorage") -@app.blob_input(arg_name="cachedClient2", - path="python-worker-tests/test-blobclient-triggered.txt", - connection="AzureWebJobsStorage") -@app.route(route="blob_cache3") -def blob_cache3(req: func.HttpRequest, - cachedClient: blob.BlobClient, - cachedClient2: blob.BlobClient) -> func.HttpResponse: - return func.HttpResponse("Client 1: " + repr(cachedClient) - + " | Client 2: " + repr(cachedClient2)) - - @app.function_name(name="invalid_connection_info") @app.blob_input(arg_name="client", path="python-worker-tests/test-blobclient-triggered.txt", diff --git a/tests/extension_tests/deferred_bindings_tests/test_deferred_bindings_blob_functions.py b/tests/extension_tests/deferred_bindings_tests/test_deferred_bindings_blob_functions.py index cedd910ad..b9e4bd2a1 100644 --- a/tests/extension_tests/deferred_bindings_tests/test_deferred_bindings_blob_functions.py +++ b/tests/extension_tests/deferred_bindings_tests/test_deferred_bindings_blob_functions.py @@ -171,64 +171,6 @@ def test_type_undefined(self): self.assertEqual(r.status_code, 200) self.assertEqual(r.text, 'test-data') - @unittest.skipIf(sys.version_info.minor >= 13, "For python 3.13+," - "the cache is maintained in the ext and TBD.") - def test_caching(self): - ''' - The cache returns the same type based on resource and function name. - Two different functions with clients that access the same resource - will have two different clients. This tests that the same client - is returned for each invocation and that the clients are different - between the two functions. - ''' - - r = self.webhost.request('GET', 'blob_cache') - r2 = self.webhost.request('GET', 'blob_cache2') - self.assertEqual(r.status_code, 200) - self.assertEqual(r2.status_code, 200) - client = r.text - client2 = r2.text - self.assertNotEqual(client, client2) - - r = self.webhost.request('GET', 'blob_cache') - r2 = self.webhost.request('GET', 'blob_cache2') - self.assertEqual(r.status_code, 200) - self.assertEqual(r2.status_code, 200) - self.assertEqual(r.text, client) - self.assertEqual(r2.text, client2) - self.assertNotEqual(r.text, r2.text) - - r = self.webhost.request('GET', 'blob_cache') - r2 = self.webhost.request('GET', 'blob_cache2') - self.assertEqual(r.status_code, 200) - self.assertEqual(r2.status_code, 200) - self.assertEqual(r.text, client) - self.assertEqual(r2.text, client2) - self.assertNotEqual(r.text, r2.text) - - @unittest.skipIf(sys.version_info.minor >= 13, "For python 3.13+," - "the cache is maintained in the ext and TBD.") - def test_caching_same_resource(self): - ''' - The cache returns the same type based on param name. - One functions with two clients that access the same resource - will have two different clients. This tests that the same clients - are returned for each invocation and that the clients are different - between the two bindings. - ''' - - r = self.webhost.request('GET', 'blob_cache3') - self.assertEqual(r.status_code, 200) - clients = r.text.split(" | ") - self.assertNotEqual(clients[0], clients[1]) - - r2 = self.webhost.request('GET', 'blob_cache3') - self.assertEqual(r2.status_code, 200) - clients_second_call = r2.text.split(" | ") - self.assertEqual(clients[0], clients_second_call[0]) - self.assertEqual(clients[1], clients_second_call[1]) - self.assertNotEqual(clients_second_call[0], clients_second_call[1]) - def test_failed_client_creation(self): r = self.webhost.request('GET', 'invalid_connection_info') # Without the http_v2_enabled default definition, this request would time out.