The py/gaas_server_proxy.py module defines the ServerProxy class. This class is crucial for enabling Python code running within the GAAS TCP server environment (handled by gaas_tcp_server_handler.py) to make calls back to the SEMOSS Java backend.
- Purpose: The
ServerProxyacts as a client or bridge from the Python side of GAAS to the main SEMOSS Java application. It allows Python functions or tools (likeDatabaseEngine,ModelEngine, etc., defined in othergaas_gpt_*.pyfiles) to invoke operations on the Java side, such as executing Pixel scripts (Reactors) or calling methods on specific JavaIEngineinstances. - Context: It assumes it's being used within the context of a
TCPServerHandlerinstance, from which it gets a reference to the server (self.server = TCPServerHandler.da_server) to manage communication and synchronization.
The constructor __init__(self):
- Initializes a
threading.Condition()object (self.condition) which is used for synchronizing threads when waiting for a response from the Java backend. - It retrieves a reference to the active
TCPServerHandlerinstance viaTCPServerHandler.da_server. This static attribute inTCPServerHandleris set when a handler instance is created, effectively making theServerProxyaware of the current client connection handler.
-
get_next_epoc(self) -> str:- Purpose: Generates a unique "epoc" ID (a string).
- Logic: Creates a random string prefixed with "py_" and followed by 17 random digits.
- Usage: This
epocID is used to tag requests sent to the Java backend and to match incoming responses, enabling asynchronous-like communication where Python can send a request, wait, and then be notified when the specific response arrives.
-
comm(self, epoc: str, engine_type: str, engine_id: str, method_name: str, method_args: Optional[List[Any]] = [], method_arg_types: Optional[List[str]] = [], insight_id: Optional[str] = None, operation: str = "REACTOR"):- Purpose: This is the core private communication method that sends a structured request to the SEMOSS Java backend via the
TCPServerHandler. - Inputs:
epoc(str): The unique ID for this request.engine_type(str): The type of SEMOSS engine on the Java side to target (e.g., "model", "storage", "database", "vector"). Used whenoperationis "ENGINE".engine_id(str): The ID of the specific engine instance.method_name(str): The name of the Java method to invoke on the target engine.method_args(Optional[List[Any]]): Arguments for the Java method.method_arg_types(Optional[List[str]]): Java class names for the argument types, used for reflection on the Java side.insight_id(Optional[str]): The current insight context. If not provided, it attempts to get it from thethread_local.payloadof theTCPServerHandler.operation(str, default: "REACTOR"): The type of operation being requested on the Java side (e.g., "REACTOR", "ENGINE").
- Logic:
- Constructs a
payloaddictionary (mimicking Java'sPayloadStruct) with all the provided arguments. - Registers
self.conditioninself.server.monitors(a dictionary inTCPServerHandler) using theepocas the key. This is how the handler knows which condition to notify when a response with thisepocarrives. - Acquires
self.condition. - Calls
self.server.send_request(payload)to send the payload to the connected Java client (which is the SEMOSS backend). - Calls
self.condition.wait(), causing the current Python thread to block until the Java backend sends a response with the matchingepocand theTCPServerHandlernotifies this condition. - Releases
self.conditionafter being awakened.
- Constructs a
- Note: This method itself doesn't return the response directly; the response is expected to be retrieved from
self.server.monitorsby the calling methods (callReactororcallEngine) after the wait.
- Purpose: This is the core private communication method that sends a structured request to the SEMOSS Java backend via the
-
callReactor(self, epoc: str, pixel: str, insight_id: Optional[str] = None):- Purpose: To execute a Pixel script on the SEMOSS Java backend.
- Inputs:
epoc(str): Unique ID for the request.pixel(str): The Pixel script to execute.insight_id(Optional[str]): The insight context.
- Logic:
- Retrieves the original payload from
self.server.thread_localto maintain context if needed for the new thread. - Defines an inner function
set_thread_local_payloadthat setsself.server.thread_local.payload(important for nested calls or context preservation in the new thread) and then callsself.comm(...)withoperation="REACTOR"and the Pixel script inmethod_args. - Starts a new
threading.Threadto executeset_thread_local_payload. This makes the call to Java asynchronous from the perspective of the main Python thread that invokedcallReactor, but the new thread itself blocks onself.comm. thread.join(): Waits for the new thread (and thus theself.commcall) to complete.- Retrieves the response payload from
self.server.monitors.pop(epoc). - If the response contains an exception (
"ex"key), it raises it. Otherwise, it returns the content ofnew_payload_struct["payload"].
- Retrieves the original payload from
- Output: The result of the Pixel execution from the Java backend.
-
callEngine(self, epoc: str, engine_type: str, engine_id: str, method_name: str = "None", method_args: Optional[List[Any]] = [], method_arg_types: Optional[List[str]] = [], insight_id: Optional[str] = None):- Purpose: To call a specific method on a SEMOSS
IEngineinstance on the Java backend. - Logic: Very similar to
callReactor:- It also uses a new thread to call
self.comm(...)withoperation="ENGINE"and the engine-specific details. - Waits for the thread to complete.
- Retrieves the response from
self.server.monitors. - Handles exceptions or returns the payload.
- It also uses a new thread to call
- Output: The result of the engine method call from the Java backend.
- Purpose: To call a specific method on a SEMOSS
TCPServerHandler:ServerProxyis tightly coupled withTCPServerHandler. It relies on the handler'sda_serverstatic attribute to get a reference to the active handler instance, which provides the socket connection (send_request) and themonitorsdictionary for response synchronization.- GAAS Tools (
DatabaseEngine,ModelEngine, etc.): These higher-level tool classes (likegaas_gpt_database.DatabaseEngine,gaas_gpt_model.TomcatModelEngine) inherit fromServerProxy. When these tools need to interact with the SEMOSS Java backend (e.g., to execute a query on a Java-managed database or run a Pixel script for a model), they use thecallReactororcallEnginemethods provided byServerProxy.
In essence, ServerProxy is the mechanism that allows Python code running within the GAAS TCP server environment to "call out" to the main SEMOSS Java application, execute operations there, and receive results, effectively bridging the Python and Java components of SEMOSS.