View Source Sorcery.Domain.Server (Sorcery v0.1.0)
The server component that manages domain instances and processes commands.
The DomainServer is responsible for:
- Managing domain process lifecycles
- Processing commands and generating events
- Maintaining domain state by applying events
- Handling event subscriptions
Types of Domains
Sorcery supports two types of domains:
- ID-Based Domains - Multiple instances of the same domain type, each with a unique ID
- Singleton Domains - Single instance domains that manage global state
Auto-Starting
Domains can be configured to auto-start when your application boots. This ensures that:
- All domains are ready to handle commands immediately
- Domains listening for events from other domains don't miss any events
- Event handlers are always active
Configure auto-starting in your config:
config :sorcery, :auto_start,
domains: [
MyApp.UserDomain,
MyApp.SettingsDomain
]Domains not configured for auto-start will be started on-demand when they receive their first command.
ID-Based Domains
Use these when you need multiple instances of the same domain type:
# Start and execute a command on a user domain
Sorcery.DomainServer.execute(
MyApp.UserDomain,
"user-123",
%MyApp.UserDomain.Commands.RegisterUser{
name: "John Doe",
email: "john@example.com"
}
)Singleton Domains
Use these for global state or configuration:
# Start and execute a command on a settings domain
Sorcery.DomainServer.execute(
MyApp.SettingsDomain,
%MyApp.SettingsDomain.Commands.UpdateTheme{
theme: "dark"
}
)Process Management
Each domain instance is a separate process that:
- Subscribes to the event store
- Maintains its own state
- Processes commands
- Generates and applies events
Event Handling
When events occur:
- The event is stored in the event store
- All domain processes receive the event
- Each domain filters events relevant to it
- Relevant events are applied to update state
Process Registry
Domain processes are registered with unique names:
- ID-based domains:
{DomainModule, "id"} - Singleton domains:
DomainModule
This ensures:
- Only one process per domain instance
- Easy lookup of existing processes
- Automatic process cleanup on termination
Summary
Functions
Returns a specification to start this module under a supervisor.
Executes a command on a domain.
Gets the current state of a domain instance.
Initializes a domain process with its initial state.
Starts a new DomainServer process.
Starts a singleton instance of a domain. This is used for auto-starting domains at application boot.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
Executes a command on a domain.
This is the main entry point for changing domain state. It will:
- Start the domain process if it doesn't exist
- Send the command to the process
- Handle command validation
- Generate and store events
- Apply events to update state
Examples
For ID-based domains:
Sorcery.DomainServer.execute(
MyApp.UserDomain,
"user-123",
%MyApp.UserDomain.Commands.RegisterUser{
name: "John Doe",
email: "john@example.com"
}
)For singleton domains:
Sorcery.DomainServer.execute(
MyApp.SettingsDomain,
%MyApp.SettingsDomain.Commands.UpdateTheme{
theme: "dark"
}
)Returns
:ok- Command succeeded{:error, reason}- Command failed with reason
Gets the current state of a domain instance.
Arguments
domain_module- The domain moduleid- The instance ID (or nil for singleton domains)
Returns
{:ok, state}- The current state of the domain{:error, :not_found}- If the domain instance doesn't exist
Initializes a domain process with its initial state.
The process will:
- Subscribe to the event store
- Load historical events
- Build initial state by applying events
Starts a new DomainServer process.
Arguments
Can be called in two ways:
With module and ID:
start_link(domain_module, id_or_command, maybe_command)With keyword options:
start_link(domain: domain_module, id: id)
Starts a singleton instance of a domain. This is used for auto-starting domains at application boot.