TantivyEx.ResourceManager (TantivyEx v0.4.1)
View SourceComprehensive resource management and lifecycle control for TantivyEx.
This module provides proper resource cleanup, lifecycle management, and resource pooling to ensure efficient resource usage and prevent resource leaks in TantivyEx operations.
Features
- Resource Lifecycle Management: Automatic tracking and cleanup
- Resource Pooling: Efficient reuse of expensive resources
- Leak Detection: Detection and prevention of resource leaks
- Graceful Shutdown: Proper cleanup during system shutdown
- Resource Monitoring: Real-time resource usage tracking
- Automatic Cleanup: Cleanup based on usage patterns and memory pressure
Resource Types
The system manages several types of resources:
- Index Resources: Index instances and their associated files
- Writer Resources: Index writers with their buffer management
- Reader Resources: Index readers and searchers
- Query Resources: Query parsers and compiled queries
- Native Resources: Native Rust objects and memory allocations
- Cache Resources: Various caches and temporary data
Configuration
TantivyEx.ResourceManager.configure(%{
# Resource limits
max_writers: 10,
max_readers: 50,
max_cached_queries: 1000,
# Cleanup policies
cleanup_interval_ms: 30_000,
idle_timeout_ms: 300_000, # 5 minutes
force_cleanup_threshold: 0.9, # 90% resource usage
# Pool configuration
enable_pooling: true,
pool_min_size: 2,
pool_max_size: 10,
pool_checkout_timeout_ms: 5000,
# Monitoring
track_usage: true,
leak_detection: true,
usage_logging: true
})Usage
# Start the resource manager
{:ok, _pid} = TantivyEx.ResourceManager.start_link()
# Register resources for management
{:ok, writer} = TantivyEx.IndexWriter.new(index, 50_000_000)
:ok = TantivyEx.ResourceManager.register(writer, :writer, &IndexWriter.close/1)
# Use pooled resources
TantivyEx.ResourceManager.with_pooled_reader(index, fn reader ->
TantivyEx.Searcher.search(reader, query, 10)
end)
# Manual resource management
{:ok, stats} = TantivyEx.ResourceManager.get_resource_stats()
:ok = TantivyEx.ResourceManager.cleanup_idle_resources()
:ok = TantivyEx.ResourceManager.force_cleanup()
Summary
Functions
Checks in a resource to a pool.
Checks out a resource from a pool.
Returns a specification to start this module under a supervisor.
Forces cleanup of all idle resources.
Cleans up a specific resource by ID.
Configures the resource manager.
Creates a resource pool for a specific resource type.
Destroys a resource pool.
Detects potential resource leaks.
Forces cleanup of all resources (emergency cleanup).
Gets a specific resource by ID.
Gets current resource statistics.
Lists all registered resources.
Registers a resource for management.
Registers a resource with simplified API for tests.
Starts the resource manager.
Unregisters a resource from management.
Unregisters a resource by ID.
Executes a function with a pooled resource.
Types
@type pool_config() :: %{ min_size: non_neg_integer(), max_size: non_neg_integer(), checkout_timeout_ms: non_neg_integer(), idle_timeout_ms: non_neg_integer() }
@type resource_info() :: %{ resource: any(), type: resource_type(), cleanup_fun: function(), created_at: DateTime.t(), last_used: DateTime.t(), usage_count: non_neg_integer(), pool_id: String.t() | nil, metadata: map() }
@type resource_stats() :: %{ total_resources: non_neg_integer(), by_type: map(), pool_stats: map(), cleanup_stats: map(), memory_usage: map() }
@type resource_type() :: :writer | :reader | :index | :query | :native | :cache
Functions
@spec checkin(String.t(), any()) :: :ok | {:error, TantivyEx.Error.t()}
Checks in a resource to a pool.
@spec checkout(String.t(), non_neg_integer()) :: {:ok, any()} | {:error, :timeout | :pool_not_found | TantivyEx.Error.t()}
Checks out a resource from a pool.
Parameters
pool_id- Pool identifiertimeout- Checkout timeout in milliseconds
Returns
{:ok, resource}- Successfully checked out resource{:error, :timeout}- Checkout timed out{:error, :pool_not_found}- Pool doesn't exist
Examples
iex> {:ok, reader} = TantivyEx.ResourceManager.checkout("readers", 5000)
iex> # Use reader
iex> :ok = TantivyEx.ResourceManager.checkin("readers", reader)
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec cleanup_idle_resources() :: :ok | {:error, TantivyEx.Error.t()}
Forces cleanup of all idle resources.
@spec cleanup_resource(String.t()) :: :ok | {:error, :not_found | TantivyEx.Error.t()}
Cleans up a specific resource by ID.
@spec configure(map()) :: :ok | {:error, TantivyEx.Error.t()}
Configures the resource manager.
@spec create_pool(String.t(), resource_type(), function(), pool_config()) :: :ok | {:error, TantivyEx.Error.t()}
Creates a resource pool for a specific resource type.
Parameters
pool_id- Unique identifier for the pooltype- Resource typefactory_fun- Function to create new resourcesconfig- Pool configuration
Examples
iex> TantivyEx.ResourceManager.create_pool("readers", :reader,
...> fn -> TantivyEx.IndexReader.new(index) end,
...> %{min_size: 2, max_size: 10}
...> )
:ok
@spec destroy_pool(String.t()) :: :ok | {:error, TantivyEx.Error.t()}
Destroys a resource pool.
@spec detect_leaks() :: {:ok, [map()]} | {:error, TantivyEx.Error.t()}
Detects potential resource leaks.
Returns
Returns a list of resources that may be leaked based on usage patterns.
@spec force_cleanup() :: :ok | {:error, TantivyEx.Error.t()}
Forces cleanup of all resources (emergency cleanup).
Gets a specific resource by ID.
@spec get_resource_stats() :: {:ok, resource_stats()} | {:error, TantivyEx.Error.t()}
Gets current resource statistics.
@spec list_resources() :: list()
Lists all registered resources.
@spec register(any(), resource_type(), function(), map()) :: :ok | {:error, TantivyEx.Error.t()}
Registers a resource for management.
Parameters
resource- The resource to managetype- The resource typecleanup_fun- Function to call for cleanupmetadata- Optional metadata
Examples
iex> TantivyEx.ResourceManager.register(writer, :writer, &IndexWriter.close/1)
:ok
@spec register_resource(String.t(), map()) :: :ok | {:error, TantivyEx.Error.t()}
Registers a resource with simplified API for tests.
@spec start_link(keyword()) :: GenServer.on_start()
Starts the resource manager.
@spec unregister(any()) :: :ok
Unregisters a resource from management.
@spec unregister_resource(String.t()) :: :ok | {:error, TantivyEx.Error.t()}
Unregisters a resource by ID.
@spec with_pooled_resource(String.t(), function(), non_neg_integer()) :: {:ok, any()} | {:error, TantivyEx.Error.t()}
Executes a function with a pooled resource.
The resource is automatically checked out before the function execution and checked back in afterward, even if an error occurs.
Parameters
pool_id- Pool identifierfun- Function to execute with the resourcetimeout- Checkout timeout
Examples
iex> TantivyEx.ResourceManager.with_pooled_resource("readers", fn reader ->
...> TantivyEx.Searcher.search(reader, query, 10)
...> end)
{:ok, search_results}