Module: Takagi::Profiles

Defined in:
lib/takagi/profiles.rb

Overview

Load profiles for different IoT/CoAP use cases

Provides predefined configurations for common scenarios to simplify performance tuning without manual process/thread configuration.

Examples:

Using a profile

class TelemetryController < Takagi::Controller
  configure do
    profile :high_throughput
  end
end

Profile with overrides

class TelemetryController < Takagi::Controller
  configure do
    profile :high_throughput
    set :processes, 16  # Override default
  end
end

Constant Summary collapse

PROFILES =

Predefined load profiles for common IoT scenarios

{
  # For devices with minimal traffic (single worker)
  # Use case: Status endpoints, health checks on constrained devices
  minimal: {
    processes: 1,
    threads: 1,
    description: 'Single-threaded, lowest resource usage for constrained devices'
  }.freeze,

  # For typical low-traffic device endpoints
  # Use case: Configuration, device status, infrequent queries
  low_traffic: {
    processes: 1,
    threads: 2,
    description: 'Configuration, status endpoints with light traffic'
  }.freeze,

  # For observable endpoints with long-lived connections
  # Use case: CoAP Observe, streaming sensor data, push notifications
  long_lived: {
    processes: 2,
    threads: 8,
    description: 'Observable resources, long-lived connections (CoAP Observe)'
  }.freeze,

  # For high-volume sensor data ingestion
  # Use case: Telemetry, sensor data from many devices, high req/sec
  high_throughput: {
    processes: 8,
    threads: 4,
    description: 'High-volume sensor telemetry and data ingestion'
  }.freeze,

  # For firmware updates, images, large file transfers
  # Use case: OTA updates, firmware downloads, large payloads
  large_payloads: {
    processes: 2,
    threads: 2,
    buffer_size: 10 * 1024 * 1024, # 10MB
    description: 'Firmware updates, file transfers, large payloads'
  }.freeze,

  # Custom configuration (must specify all parameters)
  # Use case: Fine-tuned performance for specific requirements
  custom: {
    processes: nil,
    threads: nil,
    description: 'User-defined custom configuration'
  }.freeze
}.freeze

Class Method Summary collapse

Class Method Details

.apply(name, overrides = {}) ⇒ Hash

Apply a profile to a configuration hash

Examples:

Profiles.apply(:high_throughput, processes: 16)
# => { processes: 16, threads: 4, description: '...' }

Parameters:

  • name (Symbol)

    Profile name

  • overrides (Hash) (defaults to: {})

    Optional overrides

Returns:

  • (Hash)

    Merged configuration

Raises:

  • (ArgumentError)


166
167
168
169
170
171
172
173
# File 'lib/takagi/profiles.rb', line 166

def apply(name, overrides = {})
  profile = get(name)
  raise ArgumentError, "Unknown profile: #{name}" unless profile

  merged = profile.merge(overrides)
  validate!(name, merged)
  merged
end

.availableArray<Symbol>

Get all available profile names

Examples:

Profiles.available
# => [:minimal, :low_traffic, :long_lived, :high_throughput, :large_payloads, :custom]

Returns:

  • (Array<Symbol>)

    List of profile names



108
109
110
# File 'lib/takagi/profiles.rb', line 108

def available
  PROFILES.keys
end

.exists?(name) ⇒ Boolean

Check if a profile exists

Examples:

Profiles.exists?(:high_throughput)  # => true
Profiles.exists?(:unknown)          # => false

Parameters:

  • name (Symbol)

    Profile name

Returns:

  • (Boolean)

    true if profile exists



97
98
99
# File 'lib/takagi/profiles.rb', line 97

def exists?(name)
  PROFILES.key?(name)
end

.get(name) ⇒ Hash?

Get a profile by name

Examples:

Profiles.get(:high_throughput)
# => { processes: 8, threads: 4, description: '...' }

Parameters:

  • name (Symbol)

    Profile name

Returns:

  • (Hash, nil)

    Profile configuration or nil if not found



85
86
87
# File 'lib/takagi/profiles.rb', line 85

def get(name)
  PROFILES[name]&.dup # Return copy to prevent modification
end

.summaryString

Get human-readable summary of all profiles

Examples:

puts Profiles.summary

Returns:

  • (String)

    Formatted summary



118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/takagi/profiles.rb', line 118

def summary
  lines = ['Available Load Profiles:']
  PROFILES.each do |name, config|
    lines << ''
    lines << "  #{name}:"
    lines << "    Description: #{config[:description]}"
    lines << "    Processes: #{config[:processes] || 'custom'}"
    lines << "    Threads: #{config[:threads] || 'custom'}"
    lines << "    Buffer Size: #{config[:buffer_size]}" if config[:buffer_size]
  end
  lines.join("\n")
end

.validate!(name, config = nil) ⇒ void

This method returns an undefined value.

Validate profile configuration

Parameters:

  • name (Symbol)

    Profile name

  • config (Hash) (defaults to: nil)

    Configuration to validate

Raises:

  • (ArgumentError)

    if profile is invalid



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/takagi/profiles.rb', line 138

def validate!(name, config = nil)
  config ||= get(name)

  raise ArgumentError, "Unknown profile: #{name}" unless exists?(name)

  if name == :custom
    raise ArgumentError, 'Custom profile requires :processes' unless config[:processes]
    raise ArgumentError, 'Custom profile requires :threads' unless config[:threads]
  end

  if config[:processes] && config[:processes] < 1
    raise ArgumentError, 'Processes must be >= 1'
  end

  if config[:threads] && config[:threads] < 1
    raise ArgumentError, 'Threads must be >= 1'
  end
end