# Dynamic Supervisor
[](https://hex.pm/packages/dynamic_supervisor)
[](https://github.com/longlene/dynamic_supervisor/blob/master/LICENSE)
An Erlang library providing a supervisor optimized for dynamically spawning children. This is a port of Elixir's DynamicSupervisor, maintaining a similar API while following Erlang conventions.
## Installation
Add to your `rebar.config`:
```erlang
{deps, [
{dynamic_supervisor, "1.0.0"}
]}.
```
Or for hex.pm:
```erlang
{deps, [
{dynamic_supervisor, {hex, dynamic_supervisor, "1.0.0"}}
]}.
```
## Overview
The `dynamic_supervisor` module provides a supervisor optimized for dynamically starting children. Unlike the standard supervisor which is designed for static children started in order, a dynamic supervisor:
- Starts with no children
- Allows starting children on demand via `start_child/2`
- Has no ordering between children
- Can efficiently handle millions of children
- Executes operations like shutdown concurrently
## Features
- **One-for-one supervision strategy**: Only the failed child is restarted
- **Dynamic child management**: Add and remove children at runtime
- **Restart strategies**: Support for `permanent`, `transient`, and `temporary` restart types
- **Maximum children limit**: Optional limit on the number of concurrent children
- **Extra arguments**: Arguments that are prepended to child start arguments
- **Full OTP compliance**: Implements standard supervisor behaviors
## API
### Starting a Dynamic Supervisor
```erlang
{ok, Pid} = dynamic_supervisor:start_link([
{name, {local, my_supervisor}},
{strategy, one_for_one},
{max_restarts, 3},
{max_seconds, 5},
{max_children, 1000}
]).
```
### Starting Children
```erlang
%% Full child specification
{ok, ChildPid} = dynamic_supervisor:start_child(my_supervisor,
#{id => worker1,
start => {my_worker, start_link, [Arg1, Arg2]},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [my_worker]}).
%% Simplified specification (using defaults)
{ok, ChildPid2} = dynamic_supervisor:start_child(my_supervisor,
#{id => worker2,
start => {my_worker, start_link, []}}).
```
### Managing Children
```erlang
%% List all children
Children = dynamic_supervisor:which_children(my_supervisor).
%% Count children
Counts = dynamic_supervisor:count_children(my_supervisor).
%% Returns: #{specs => N, active => N, supervisors => N, workers => N}
%% Terminate a specific child
ok = dynamic_supervisor:terminate_child(my_supervisor, ChildPid).
%% Stop the supervisor
ok = dynamic_supervisor:stop(my_supervisor).
```
## Examples
### Basic Usage
See `example_usage.erl` for a complete example:
```bash
make example
```
### Running Tests
```bash
make test
```
### Interactive Shell
```bash
make shell
```
Then in the Erlang shell, you need to add the examples path:
```erlang
1> code:add_path("examples").
2> example_usage:demo().
```
## Differences from Elixir's DynamicSupervisor
1. **Module naming**: Uses Erlang convention (`dynamic_supervisor` instead of `DynamicSupervisor`)
2. **Options format**: Uses proplist format `[{key, value}]` instead of keyword lists
3. **Child specs**: Supports both map-based specs and traditional tuple-based specs
4. **Return values**: Uses standard Erlang return conventions
5. **Error handling**: Uses Erlang's error_logger instead of Elixir's Logger
## Implementation Notes
- Built on top of gen_server behavior
- Uses maps for efficient child storage
- Implements OTP supervisor protocols
- Supports hot code upgrades via `code_change/3`
- Proper cleanup on termination with concurrent child shutdown
## Files
- `src/dynamic_supervisor.erl` - Main implementation
- `examples/counter.erl` - Example gen_server for demonstrations
- `examples/example_usage.erl` - Usage examples
- `test/` - Test suites (EUnit and Common Test)
- `Makefile` - Build automation
## Building
```bash
make compile # Compile the library
make test # Run tests
make example # Run example
make shell # Start Erlang shell
```
## Requirements
- Erlang/OTP 21 or later (for map support)
- rebar3 (for building)
## License
Apache 2.0 - This implementation follows the structure of Elixir's DynamicSupervisor but is written entirely in Erlang.