Active Object
published: ⏰ 12This article describes one implementation of the Active Object pattern that simplifies the management of asynchronous operations.
What is an Active Object?
The Active Object pattern decouples method execution from method invocation for objects that each reside in their own thread of control (Source). This separation allows methods to be called asynchronously, which in theory can help improve the responsiveness and scalability of applications.
Key components:
- Proxy/Interface – acts as an interface to the Active Object. It receives method calls and queues them.
- Scheduler/Dispatcher – manages the order in which queued requests are executed.
- Servant/Object Implementation – contains the actual implementation of the methods. It executes requests on its own thread.
- Request Queue – holds the queue of requests until they are processed by the Servant.
- Messages/Events – encapsulate method calls and their parameters, allowing them to be queued and processed.
Benefits:
- Response Speed – by separating method execution from invocation, the Active Object pattern avoids blocking the main thread of execution.
- Multithreading Simplification – the pattern abstracts away the complexities of thread management and synchronization, making it easier to write parallel code.
- Scalability – the pattern can be easily scaled by adding more processing threads, which can help improve performance on multi-core systems.
Example use cases:
- Non-blocking requests – perform long-running requests for an object’s state or call its operations without affecting the main application thread.
- Call chain – the ability to create a sequential chain of non-blocking calls to multiple objects.
Implementation
This implementation very specific for next purposes:
- Asynchronous Method Calls – methods execute asynchronously, allowing the caller to continue performing other tasks.
- Thread-Safe Processing – ensures that method calls are thread-safe and do not interfere with each other.
- Request Queue Management – efficiently manages the request queue to ensure that requests are processed in the correct order.
- Dependency Management – ensures strict control of dependencies between objects.
- Customizable Lifecycles – allows you to customize object lifecycles, including initialization and finalization.
- Single Dispatcher – uses a single dispatcher to manage all active objects.
- High Processing Speed – ensures high message processing speed.
Lifecycle Management:
Usage Examples
- User Interface – provides access to the data table from the user interface.
- Data Table – represents a data table that can be in different states (e.g. migrating, creating, deleting, etc.). Dependent on Data Source.
- Data Source – represents a data source that can be in different states (e.g. creating, connecting, closing, etc.). Dependent on Data Table and interacts with external resources such as databases or file systems.
The Data Table and Data Source are active objects that can be in different states. The main problem we need to solve is how to manage their lifecycles and dependencies, ensuring proper initialization of the Data Source before the Data Table is used.
More complex example with ETL pipeline:
- User Interface – provides access to the pipeline from the user interface.
- Pipeline – represents the data processing pipeline, which can be in different states (e.g., running, paused, stopped, etc.). Depends on Source Endpoint, Transformer, and Target Endpoint.
- Source Endpoint – represents the source endpoint, which can be in different states (e.g., connecting, connected, disconnected, etc.). Interacts with external resources such as databases or file systems.
- Transformer – represents the transformer, which can be in different states (e.g., processing, stopping, stopped, etc.). Depends on back-end scripts or services.
- Target Endpoint – represents the target endpoint, which can be in different states (e.g., connecting, connected, disconnected, etc.). It interacts with external resources such as databases or file systems.
The Pipeline, Source Endpoint, Transformer, and Target Endpoint are active objects.