Date: 2025-03-10
Status
Proposed
Context
The Codexis system needs sophisticated asset management for handling various types of assets (images, SVG files, cover images) across different output formats. The asset management system must handle:
- Asset discovery and classification
- Format-specific processing
- Optimization and compression
- Caching and reuse
- Validation and verification
Decision
We will implement a comprehensive asset management system with the following components:
1. Asset Registry
defmodule Codexis.Assets.Registry do
use GenServer
defmodule Asset do
defstruct [:id, :path, :type, :metadata, :variants]
end
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
@impl true
def init(_opts) do
{:ok, %{assets: %{}, variants: %{}}}
end
def register_asset(path, type, metadata \\ %{}) do
GenServer.call(__MODULE__, {:register, path, type, metadata})
end
def get_asset(id) do
GenServer.call(__MODULE__, {:get, id})
end
def get_variant(asset_id, format) do
GenServer.call(__MODULE__, {:get_variant, asset_id, format})
end
end
2. Asset Processor Pipeline
defmodule Codexis.Assets.Processor do
def process_asset(asset = %Asset{}) do
with {:ok, asset} <- validate_asset(asset),
{:ok, asset} <- optimize_asset(asset),
{:ok, asset} <- generate_variants(asset) do
{:ok, asset}
end
end
defp validate_asset(asset) do
case asset.type do
:image -> validate_image(asset)
:svg -> validate_svg(asset)
:cover -> validate_cover(asset)
_ -> {:error, :unsupported_asset_type}
end
end
defp optimize_asset(asset) do
case asset.type do
:image -> optimize_image(asset)
:svg -> optimize_svg(asset)
:cover -> optimize_cover(asset)
_ -> {:ok, asset}
end
end
defp generate_variants(asset) do
variants =
supported_formats(asset.type)
|> Task.async_stream(fn format ->
generate_variant(asset, format)
end)
|> Enum.reduce(%{}, fn {:ok, {format, path}}, acc ->
Map.put(acc, format, path)
end)
{:ok, %{asset | variants: variants}}
end
end
3. Asset Cache
defmodule Codexis.Assets.Cache do
use GenServer
@cache_dir "priv/asset_cache"
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
@impl true
def init(_opts) do
File.mkdir_p!(@cache_dir)
{:ok, %{}}
end
def get_cached(asset_id, variant) do
GenServer.call(__MODULE__, {:get, asset_id, variant})
end
def cache_asset(asset_id, variant, path) do
GenServer.cast(__MODULE__, {:cache, asset_id, variant, path})
end
def invalidate(asset_id) do
GenServer.cast(__MODULE__, {:invalidate, asset_id})
end
end
4. Asset Validation
defmodule Codexis.Assets.Validator do
def validate_image(path) do
with {:ok, info} <- identify_image(path),
:ok <- validate_dimensions(info),
:ok <- validate_format(info),
:ok <- validate_color_space(info) do
{:ok, info}
end
end
def validate_svg(path) do
with {:ok, doc} <- File.read(path),
{:ok, parsed} <- parse_svg(doc),
:ok <- validate_svg_structure(parsed) do
{:ok, parsed}
end
end
def validate_cover(path) do
with {:ok, info} <- validate_image(path),
:ok <- validate_cover_requirements(info) do
{:ok, info}
end
end
end
5. Asset Optimization
defmodule Codexis.Assets.Optimizer do
def optimize_image(path, options \\ []) do
with {:ok, temp_path} <- create_temp_copy(path),
:ok <- run_image_optimization(temp_path, options) do
{:ok, temp_path}
end
end
def optimize_svg(path, options \\ []) do
with {:ok, content} <- File.read(path),
{:ok, optimized} <- optimize_svg_content(content, options),
{:ok, temp_path} <- write_temp_file(optimized) do
{:ok, temp_path}
end
end
defp run_image_optimization(path, options) do
# Use image optimization tools based on format
end
defp optimize_svg_content(content, options) do
# Use SVGO or similar tool
end
end
Consequences
Positive
- Centralized Management: Single system for all asset handling
- Optimization: Automatic asset optimization for each format
- Caching: Efficient reuse of processed assets
- Validation: Comprehensive asset validation
- Parallelization: Concurrent asset processing
Negative
- Complexity: More complex than simple file operations
- Dependencies: Requires external tools for optimization
- Storage: Needs space for cached variants
Risks
- Performance: Must monitor processing overhead
- Storage Growth: Need strategy for cache cleanup
- Tool Dependencies: External tool version management
Compliance
Asset management must:
- Validate all assets before processing
- Optimize assets appropriately
- Generate required variants
- Maintain proper caching
- Clean up temporary files
Notes
- Monitor cache size and implement cleanup strategy
- Document external tool requirements
- Consider distributed processing for large assets
- Implement proper error handling for external tools