This page contains technical details about PIPEFORCE and the software and architecture patterns used inside it. This know-how is not required to use PIPEFORCE, but can help to better understand how it works in the backend in case you need to customize PIPEFORCE or develop core features.
Command Bus Pattern
Also known as Command Dispatcher Pattern, Command Broker Pattern, Command Processor Pattern.
This is one of the core concepts used in PIPEFORCE.
The Command Bus Pattern is a software design pattern that functions like a command dispatcher in an application. Its primary role is to decouple the execution of a command from its initiation. This means that the part of the code that requests something to be done is separated from the logic that actually performs the task.
Here's a breakdown of how it works:
Command (or Command Message): A command message is a simple object containing all the necessary data to perform an action. It's akin to a detailed instruction or request.
Command Bus: This is the central part of the pattern. The Command Bus takes a command message and then figures out who should handle it. It acts like a router, determining the path a command should take based on its type or content.
Command Handler: For each type of command, there is a corresponding handler. A handler is a piece of code responsible for executing the action defined in the command message. It's where the actual logic of the application resides.
The beauty of the Command Bus Pattern lies in its ability to simplify complex application workflows. By separating the request for an action from the execution, it enhances maintainability, scalability, and testability of the code. It's particularly beneficial in large, complex systems where operations and business logic need to be clearly separated.
The pattern also supports flexibility and extensibility. New commands and handlers can be added without disrupting existing code, and it's easier to modify the behavior of specific parts of the application without affecting others.
The Command Bus Pattern offers significant advantages in the context of microservices and message-driven architectures used in PIPEFORCE. These advantages stem from the pattern's inherent design principles, which align well with the needs of distributed, loosely-coupled systems like microservices. Here's an overview:
Decoupling of Components: In microservices, it's crucial to have independent services that are loosely coupled. The Command Bus Pattern achieves this by separating the command sender from the receiver. This means a service can issue commands without needing to know about the inner workings of other services, thereby promoting independence and reducing inter-service dependencies.
Improved Scalability: Microservices architectures thrive on the ability to scale individual components independently. The Command Bus Pattern supports this by allowing new handlers to be added for new commands without affecting existing services. This flexibility makes it easier to scale and evolve the system over time.
Enhanced Flexibility and Maintainability: By defining clear boundaries and interfaces (commands and handlers), the pattern makes it easier to modify, replace, or extend specific parts of the system without impacting others. This is particularly beneficial in a microservices environment where different teams might be responsible for different services.
Facilitates a Clean Contract-Driven Design: The use of commands as data transfer objects (DTOs) helps in defining clear contracts between different services. This contract-driven approach is essential in microservices for ensuring that services interact consistently and reliably.
Simplifies Complex Workflows: In message-driven systems, managing workflows can become complex. The Command Bus Pattern provides a structured way to handle requests and process them, making it easier to manage complex workflows and ensuring that each piece of the workflow is handled by the appropriate component.
Supports Asynchronous Processing: Message-driven architectures often rely on asynchronous communication. The Command Bus Pattern naturally supports asynchronous processing, as commands can be placed onto a bus and handled independently of the sender's process.
Error Handling and Recovery: The pattern allows for centralized error handling and recovery mechanisms within the command bus. This is crucial in distributed systems where failures need to be managed gracefully.
In summary, the Command Bus Pattern aligns well with the principles of microservices and message-driven architectures by promoting decoupling, scalability, flexibility, and maintainability. It provides a structured approach to handling requests and operations, which is essential in PIPEFORCE.
The Command Query Responsibility Segregation (CQRS) pattern is an architectural design pattern used inside PIPEFORCE that separates the operations that modify data (commands) from the operations that retrieve data (queries). This separation allows for more efficient and scalable systems, as it enables independent scaling and optimization of the read and write components of a system.
In CQRS, the "command" side handles tasks that change the state of the data, such as creating, updating, or deleting records. These commands are often processed asynchronously and can be queued, ensuring that the system can handle large volumes of write operations efficiently.
On the other hand, the "query" side deals with retrieving data without affecting its state. This can involve simple data lookups or complex queries to aggregate data. Since these operations don't change the underlying data, they can often be executed with more flexibility, such as using read replicas or caching mechanisms to improve performance.
Note: In PIPEFORCE any type of server-side action is called a command regardless of whether it reads or writes data. But there is a subset of commands limited to read-only tasks which relates to the “query” actions as described here. These commands typically do have one of these suffixes:
For example: property.list in order to return a filtered list of properties or config.get to retrieve a config item.
The Command Bus Pattern mentioned above is closely linked to the CQRS pattern. It acts as a mediator that routes command messages to the appropriate command handler. In a CQRS system, commands are sent to the command bus, which then delegates them to the specific part of the system responsible for handling that command. This pattern simplifies the process of executing commands, as the command bus abstracts the routing and dispatching logic, making the system more maintainable and scalable.
By using a command bus, a CQRS-based system can efficiently manage and process commands, ensuring that they are handled by the appropriate services or components, while maintaining a clear separation between commands and queries.