Caveats#
Multiprocessing / Multithreading Usage#
When using Serverless ADR in applications that involve multiple processes or threads, Serverless ADR modifies the Python process environment and dynamically loads required modules from the Ansys installation during setup. Because of this design, proper initialization and lifecycle management are critical when using Serverless ADR in applications involving multiple processes or threads.
Process-Level Initialization#
The
ADR.setup()
method configures Serverless ADR for the entire process.When your application uses multiprocessing (e.g., the
multiprocessing
module, Gunicorn workers, or other process-based concurrency), each process must callADR.setup()
before accessing Serverless ADR features.If
setup()
is not called in a new process, ADR APIs will fail or behave unpredictably due to missing environment configuration.
Example: Multiprocessing with Serverless ADR
import multiprocessing
from ansys.dynamicreporting.core.serverless import ADR
def worker_task():
adr = ADR.get_instance()
if not adr.is_setup:
adr.setup()
# Proceed with Serverless ADR API calls here
if __name__ == "__main__":
adr = ADR(ansys_installation="/path/to/ansys", db_directory="/path/to/db")
adr.setup()
# Spawn new processes
processes = []
for _ in range(4):
p = multiprocessing.Process(target=worker_task)
p.start()
processes.append(p)
for p in processes:
p.join()
Thread-Level Behavior#
Serverless ADR configuration applies process-wide and is shared by all threads.
It is unnecessary and discouraged to call
ADR.setup()
multiple times within the same process.Ensure the main thread calls
ADR.setup()
before spawning any threads that will use Serverless ADR.Calling
setup()
concurrently or repeatedly from multiple threads can cause race conditions or inconsistent environment state.
Example: Threading with Serverless ADR
import threading
from ansys.dynamicreporting.core.serverless import ADR
def thread_task():
adr = ADR.get_instance()
# ADR is already setup in main thread, so just use it directly
# Make ADR API calls here
if __name__ == "__main__":
adr = ADR(ansys_installation="/path/to/ansys", db_directory="/path/to/db")
adr.setup() # Call once in main thread before starting other threads
threads = []
for _ in range(4):
t = threading.Thread(target=thread_task)
t.start()
threads.append(t)
for t in threads:
t.join()
Serverless ADR Usage Within Django Apps#
Serverless ADR internally configures Django settings and environment variables at the process level during
ADR.setup()
.Because Django settings are designed to be configured once per process, attempting to initialize Serverless ADR inside an existing Django application causes conflicts.
Specifically, setting up Serverless ADR tries to configure Django a second time, which is unsupported and results in errors or unpredictable behavior.
This means embedding or using Serverless ADR as a Django app within another Django project is not currently supported and strongly discouraged.
If you require integration, consider separating Serverless ADR usage into a dedicated process or microservice to avoid Django settings conflicts.
Summary and Best Practices#
Always call
ADR.setup()
once at the application startup or entry point.In multiprocessing scenarios, call
setup()
separately in each spawned process.Avoid calling
setup()
multiple times or concurrently within the same process.Share the ADR instance across threads within a process after setup completes.
Avoid embedding Serverless ADR within other Django apps due to Django configuration conflicts.
If unsure whether setup is needed, check
adr.is_setup
before calling.
By following these guidelines, you ensure stable and consistent Serverless ADR usage in complex multi-threaded or multi-process environments without risking Django conflicts.