### Install ActionMailer Balancer Gem Source: https://github.com/mailtrap/actionmailer-balancer/blob/main/README.md Instructions for adding the ActionMailer Balancer gem to a Ruby on Rails application's Gemfile and installing it. ```ruby gem 'actionmailer-balancer' ``` -------------------------------- ### Configure ActionMailer Balancer in Rails Source: https://github.com/mailtrap/actionmailer-balancer/blob/main/README.md Configuration snippet for Rails initializers to set ActionMailer's delivery method to ':balancer' and define weighted delivery methods. This includes SMTP and Sendmail examples. ```ruby Your::Application.configure do config.action_mailer.delivery_method = :balancer config.action_mailer.balancer_settings = { delivery_methods: [ { method: :smtp, settings: { user_name: username, password: password, address: host, domain: domain, port: port, authentication: auth_method }, weight: 90 }, { method: :sendmail, settings: { location: '/path/to/your/sendmail' }, weight: 10 } ] } end ``` -------------------------------- ### Action Mailer Balancer Configuration with Error Handling Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Demonstrates how to configure Action Mailer Balancer and handle potential configuration errors such as missing delivery methods or weights. It initializes the balancer with specified delivery methods and weights, then prints confirmation of the setup. ```ruby begin ActionMailer::Balancer::DeliveryMethod.new({ some_option: true }) rescue ActionMailer::Balancer::SettingsError => e puts e.message # => "No delivery methods set" end begin ActionMailer::Balancer::DeliveryMethod.new( delivery_methods: [ { method: :smtp, settings: { address: 'smtp.example.com' } }, # Missing weight! { method: :sendmail, weight: 10 } ] ) rescue ActionMailer::Balancer::SettingsError => e puts e.message # => "No weight set for delivery method smtp" end settings = { delivery_methods: [ { method: :smtp, settings: { address: 'smtp.example.com' }, weight: 50 }, { method: :sendmail, settings: { location: '/usr/sbin/sendmail' }, weight: 50 } ] } alancer = ActionMailer::Balancer::DeliveryMethod.new(settings) puts "Balancer configured with #{balancer.delivery_methods.length} methods" puts "Total weight: #{balancer.weights_sum}" ``` -------------------------------- ### Deliver Email Using Action Mailer Balancer Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Shows how to use the initialized `ActionMailer::Balancer::DeliveryMethod` instance to deliver an email. The `deliver!` method on the balancer automatically selects one of the configured delivery methods based on their assigned weights and sends the email through it. This example uses the `mail` gem to construct the email message. ```ruby require 'mail' require 'actionmailer/balancer' # Initialize balancer balancer = ActionMailer::Balancer::DeliveryMethod.new( delivery_methods: [ { method: :smtp, settings: { address: 'smtp.provider1.com' }, weight: 90 }, { method: :sendmail, settings: { location: '/usr/sbin/sendmail' }, weight: 10 } ] ) # Create a mail message message = Mail.new do from 'sender@example.com' to 'recipient@example.com' subject 'Test Email' body 'This email will be sent through a randomly selected delivery method' end # Deliver the message - balancer automatically selects method # 90% chance of using SMTP, 10% chance of using Sendmail result = balancer.deliver!(message) # Returns: Result from the selected delivery method's deliver! call ``` -------------------------------- ### Handle Action Mailer Balancer Configuration Errors Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Provides an example of how the `ActionMailer::Balancer` gem handles invalid configuration settings. It demonstrates that initializing the `DeliveryMethod` with an empty settings hash will raise an `ActionMailer::Balancer::SettingsError`, indicating that essential configuration is missing. ```ruby require 'actionmailer/balancer' # Error Case 1: Empty settings begin ActionMailer::Balancer::DeliveryMethod.new({}) rescue ActionMailer::Balancer::SettingsError => e puts e.message # => "No settings set" end ``` -------------------------------- ### Test Mailer Delivery with Balancer (RSpec, Ruby) Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt An RSpec test example demonstrating how to verify that a mailer method successfully delivers an email when the balancer is configured with the `:test` delivery method. ```ruby RSpec.describe UserMailer do it 'sends welcome email' do expect { UserMailer.welcome_email(user).deliver_now }.to change { ActionMailer::Base.deliveries.count }.by(1) email = ActionMailer::Base.deliveries.last expect(email.to).to eq([user.email]) expect(email.subject).to eq('Welcome!') end end ``` -------------------------------- ### Gradual Migration of Email Delivery Providers Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Illustrates a strategy for gradually migrating email delivery from an old provider to a new one by adjusting weights over time. This approach allows for controlled testing and rollout, starting with a small percentage on the new provider and increasing it incrementally. ```ruby # config/environments/production.rb Rails.application.configure do config.action_mailer.delivery_method = :balancer # Week 1: Start with 1% on new provider # config.action_mailer.balancer_settings = { # delivery_methods: [ # { method: :old_provider, settings: OLD_SETTINGS, weight: 99 }, # { method: :new_provider, settings: NEW_SETTINGS, weight: 1 } # ] # } # Week 2: Increase to 5% # config.action_mailer.balancer_settings = { # delivery_methods: [ # { method: :old_provider, settings: OLD_SETTINGS, weight: 95 }, # { method: :new_provider, settings: NEW_SETTINGS, weight: 5 } # ] # } # Week 3: 20% on new provider # config.action_mailer.balancer_settings = { # delivery_methods: [ # { method: :old_provider, settings: OLD_SETTINGS, weight: 80 }, # { method: :new_provider, settings: NEW_SETTINGS, weight: 20 } # ] # } # Week 4: 50/50 split config.action_mailer.balancer_settings = { delivery_methods: [ { method: :smtp, settings: { address: 'smtp.oldprovider.com', user_name: ENV['OLD_USER'], password: ENV['OLD_PASS'] }, weight: 50 }, { method: :smtp, settings: { address: 'smtp.newprovider.com', user_name: ENV['NEW_USER'], password: ENV['NEW_PASS'] }, weight: 50 } ] } # Final: 100% on new provider # config.action_mailer.balancer_settings = { # delivery_methods: [ # { method: :new_provider, settings: NEW_SETTINGS, weight: 100 } # ] # } end ``` -------------------------------- ### Initialize ActionMailer Balancer with Multiple Delivery Methods Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Demonstrates how to initialize the `ActionMailer::Balancer::DeliveryMethod` class with a configuration hash. This hash specifies an array of delivery methods, each with its own settings and a weight. The weights determine the probability of each method being selected for email delivery. It also shows basic error handling for invalid configurations. ```ruby require 'actionmailer/balancer' # Configure with multiple delivery methods and weights settings = { delivery_methods: [ { method: :smtp, settings: { user_name: 'user@example.com', password: 'secret_password', address: 'smtp.gmail.com', domain: 'example.com', port: 587, authentication: 'plain', enable_starttls_auto: true }, weight: 70 # 70% of emails }, { method: :sendmail, settings: { location: '/usr/sbin/sendmail' }, weight: 20 # 20% of emails }, { method: :mailtrap, # No settings required for some methods weight: 10 # 10% of emails } ] } begin delivery_method = ActionMailer::Balancer::DeliveryMethod.new(settings) # Returns: ActionMailer::Balancer::DeliveryMethod instance # Raises: ActionMailer::Balancer::SettingsError if configuration is invalid rescue ActionMailer::Balancer::SettingsError => e puts "Configuration error: #{e.message}" end ``` -------------------------------- ### Access Balancer Attributes at Runtime (Ruby) Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Demonstrates how to instantiate and inspect an `ActionMailer::Balancer::DeliveryMethod` object at runtime. It shows how to access configured delivery methods, their settings, and calculate the total weight and individual percentages. ```ruby require 'actionmailer/balancer' # Create balancer instance balancer = ActionMailer::Balancer::DeliveryMethod.new( delivery_methods: [ { method: :smtp, settings: { address: 'smtp.example.com' }, weight: 60 }, { method: :sendmail, settings: { location: '/usr/sbin/sendmail' }, weight: 30 }, { method: :mailtrap, weight: 10 } ] ) # Access delivery methods configuration puts "Configured methods:" balancer.delivery_methods.each do |dm| puts " - #{dm[:method]}: weight #{dm[:weight]}" puts " settings: #{dm[:settings]}" if dm[:settings] end # Output: # - smtp: weight 60 # settings: {:address=>"smtp.example.com"} # - sendmail: weight 30 # settings: {:location=>"/usr/sbin/sendmail"} # - mailtrap: weight 10 # Check total weight puts "Total weight: #{balancer.weights_sum}" # Output: Total weight: 100 # Calculate percentages balancer.delivery_methods.each do |dm| percentage = (dm[:weight].to_f / balancer.weights_sum * 100).round(2) puts "#{dm[:method]}: #{percentage}% of emails" end # Output: # smtp: 60.0% of emails # sendmail: 30.0% of emails # mailtrap: 10.0% of emails ``` -------------------------------- ### DeliveryMethod Initialization Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Initializes the ActionMailer::Balancer::DeliveryMethod with configured delivery methods and their weights. This class manages the weighted selection of delivery methods for outgoing emails. ```APIDOC ## DeliveryMethod Initialization ### Description Initializes the ActionMailer::Balancer::DeliveryMethod with configured delivery methods and their weights. This class manages the weighted selection of delivery methods for outgoing emails. ### Method `initialize(settings)` ### Parameters #### Request Body - **settings** (Hash) - Required - Configuration hash containing `delivery_methods`. - **delivery_methods** (Array) - Required - An array of delivery method configurations. - **method** (Symbol) - Required - The delivery method name (e.g., `:smtp`, `:sendmail`, `:mailtrap`). - **settings** (Hash) - Optional - Settings specific to the delivery method. - **weight** (Integer) - Required - The weight assigned to this delivery method (determines percentage of emails). ### Request Example ```ruby require 'action_mailer/balancer' settings = { delivery_methods: [ { method: :smtp, settings: { user_name: 'user@example.com', password: 'secret_password', address: 'smtp.gmail.com', domain: 'example.com', port: 587, authentication: 'plain', enable_starttls_auto: true }, weight: 70 }, { method: :sendmail, settings: { location: '/usr/sbin/sendmail' }, weight: 20 }, { method: :mailtrap, weight: 10 } ] } delivery_method = ActionMailer::Balancer::DeliveryMethod.new(settings) ``` ### Response #### Success Response (Instance) - **ActionMailer::Balancer::DeliveryMethod** - An instance of the delivery method manager. #### Error Response (Exception) - **ActionMailer::Balancer::SettingsError** - Raised if the configuration is invalid. ``` -------------------------------- ### Method Configuration Without Settings (Ruby) Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Illustrates how to configure the `ActionMailer::Balancer::DeliveryMethod` with delivery methods that do not require explicit settings (supported since v1.1.1). The balancer gracefully handles these by passing an empty hash for their settings. ```ruby require 'actionmailer/balancer' # Valid configuration with mixed settings presence settings = { delivery_methods: [ # Method with full settings { method: :smtp, settings: { address: 'smtp.example.com', port: 587, user_name: 'user@example.com', password: 'password' }, weight: 50 }, # Method with minimal settings { method: :sendmail, settings: { location: '/usr/sbin/sendmail' }, weight: 30 }, # Method with NO settings - valid since v1.1.1 { method: :test, weight: 20 # No settings key - gem handles this gracefully } ] } balancer = ActionMailer::Balancer::DeliveryMethod.new(settings) # The balancer passes empty hash {} for methods without settings # Equivalent to: message.delivery_method(:test, {}) ``` -------------------------------- ### Configure Development Mailer with Balancer (Ruby) Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Configures ActionMailer in development to use the balancer. It sends most emails (80%) to a local file for quick inspection and a smaller portion (20%) to Mailtrap for visual testing. ```ruby # config/environments/development.rb Rails.application.configure do config.action_mailer.delivery_method = :balancer # Send most emails to local log, some to Mailtrap for visual testing config.action_mailer.balancer_settings = { delivery_methods: [ # 80% to local file for fast development { method: :file, settings: { location: Rails.root.join('tmp/mails') }, weight: 80 }, # 20% to Mailtrap for inbox testing { method: :mailtrap, settings: { api_token: ENV['MAILTRAP_DEV_TOKEN'] }, weight: 20 } ] } end ``` -------------------------------- ### Error Handling and Validation Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt The gem includes validation for configuration settings and raises specific exceptions for invalid configurations, ensuring robust operation. ```APIDOC ## Error Handling and Validation ### Description The gem includes validation for configuration settings and raises specific exceptions for invalid configurations, ensuring robust operation. ### Error Types - **ActionMailer::Balancer::SettingsError** - Raised for various configuration issues, such as missing required settings or invalid weight configurations. ### Error Handling Example ```ruby require 'action_mailer/balancer' # Error Case 1: Empty settings begin ActionMailer::Balancer::DeliveryMethod.new({}) rescue ActionMailer::Balancer::SettingsError => e puts e.message # Expected output: "No settings set" end # Error Case 2: Missing required `delivery_methods` array begin ActionMailer::Balancer::DeliveryMethod.new({ some_other_key: 'value' }) rescue ActionMailer::Balancer::SettingsError => e puts e.message # Expected output: "Missing `delivery_methods` key in settings" end # Error Case 3: `weight` not set for a delivery method begin ActionMailer::Balancer::DeliveryMethod.new({ delivery_methods: [ { method: :smtp, settings: { address: 'smtp.com' } } # Missing weight ] }) rescue ActionMailer::Balancer::SettingsError => e puts e.message # Expected output: "Weight must be set for delivery method `:smtp`" end ``` ``` -------------------------------- ### Email Delivery with Weighted Selection Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Delivers an email using the `deliver!` method, which internally selects a delivery method based on configured weights and then sends the email. ```APIDOC ## Email Delivery with Weighted Selection ### Description Delivers an email using the `deliver!` method, which internally selects a delivery method based on configured weights and then sends the email. ### Method `deliver!(message)` ### Parameters #### Request Body - **message** (Mail) - Required - The email message object to deliver. ### Request Example ```ruby require 'mail' require 'action_mailer/balancer' # Initialize balancer balancer = ActionMailer::Balancer::DeliveryMethod.new( delivery_methods: [ { method: :smtp, settings: { address: 'smtp.provider1.com' }, weight: 90 }, { method: :sendmail, settings: { location: '/usr/sbin/sendmail' }, weight: 10 } ] ) # Create a mail message message = Mail.new do from 'sender@example.com' to 'recipient@example.com' subject 'Test Email' body 'This email will be sent through a randomly selected delivery method' end # Deliver the message result = balancer.deliver!(message) ``` ### Response #### Success Response (200) - **result** (Object) - The return value from the `deliver!` method of the selected delivery method. #### Response Example ```ruby # Example: If SMTP was selected and successful, this would be the result from the SMTP delivery method. ``` ``` -------------------------------- ### Configure Test Mailer with Balancer (Ruby) Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Configures ActionMailer in the test environment to exclusively use the balancer with the `:test` delivery method, which stores emails in `ActionMailer::Base.deliveries` for assertions. ```ruby # config/environments/test.rb Rails.application.configure do config.action_mailer.delivery_method = :balancer # In tests, use test mode exclusively config.action_mailer.balancer_settings = { delivery_methods: [ { method: :test, # Stores emails in ActionMailer::Base.deliveries weight: 100 } ] } end ``` -------------------------------- ### Multi-Provider Load Balancing for Email Delivery Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Configures Action Mailer Balancer to distribute email delivery load across multiple SMTP providers, such as SendGrid, Mailgun, and SparkPost. Each provider is assigned a specific weight, determining the percentage of emails it will handle. ```ruby # config/environments/production.rb Rails.application.configure do config.action_mailer.delivery_method = :balancer # Balance load across three providers config.action_mailer.balancer_settings = { delivery_methods: [ # SendGrid handles 40% of emails { method: :smtp, settings: { address: 'smtp.sendgrid.net', port: 587, user_name: ENV['SENDGRID_USERNAME'], password: ENV['SENDGRID_PASSWORD'], authentication: 'plain', enable_starttls_auto: true }, weight: 40 }, # Mailgun handles 40% of emails { method: :smtp, settings: { address: 'smtp.mailgun.org', port: 587, user_name: ENV['MAILGUN_USERNAME'], password: ENV['MAILGUN_PASSWORD'], authentication: 'plain' }, weight: 40 }, # SparkPost handles 20% of emails { method: :smtp, settings: { address: 'smtp.sparkpostmail.com', port: 587, user_name: 'SMTP_Injection', password: ENV['SPARKPOST_API_KEY'] }, weight: 20 } ] } end # Application code remains unchanged class UserMailer < ApplicationMailer def welcome_email(user) @user = user mail(to: @user.email, subject: 'Welcome!') # Automatically distributed across three providers end end # Usage UserMailer.welcome_email(user).deliver_now # 40% chance -> SendGrid # 40% chance -> Mailgun # 20% chance -> SparkPost ``` -------------------------------- ### Rails Configuration Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Configures ActionMailer Balancer within a Rails application's initializer to globally use weighted delivery methods for all outgoing emails. ```APIDOC ## Rails Configuration ### Description Configures ActionMailer Balancer within a Rails application's initializer to globally use weighted delivery methods for all outgoing emails. ### Method Set `config.action_mailer.delivery_method` and `config.action_mailer.balancer_settings` in `config/environments/*.rb`. ### Parameters #### Request Body (Configuration) - **config.action_mailer.delivery_method** (Symbol) - Set to `:balancer` to enable the gem. - **config.action_mailer.balancer_settings** (Hash) - Configuration hash for the balancer, identical to the `settings` hash used in `DeliveryMethod.new`. - **delivery_methods** (Array) - Required - Array of delivery method configurations with weights. ### Request Example ```ruby # config/environments/production.rb Rails.application.configure do # Set balancer as the delivery method config.action_mailer.delivery_method = :balancer # Configure weighted distribution for gradual migration config.action_mailer.balancer_settings = { delivery_methods: [ { method: :smtp, settings: { user_name: ENV['OLD_SMTP_USER'], password: ENV['OLD_SMTP_PASS'], address: 'smtp.oldprovider.com', port: 587, authentication: 'plain' }, weight: 85 }, { method: :smtp, settings: { user_name: ENV['NEW_SMTP_USER'], password: ENV['NEW_SMTP_PASS'], address: 'smtp.newprovider.com', port: 587, authentication: 'plain' }, weight: 15 } ] } end ``` ### Usage Example ```ruby # In your Rails application, you can now send emails as usual: # UserMailer.welcome_email(@user).deliver_later # OrderMailer.confirmation(@order).deliver_now # The balancer will automatically distribute them based on the configured weights. ``` ``` -------------------------------- ### Configure Production Mailer with Balancer (Ruby) Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Configures ActionMailer in production to use the balancer delivery method. It distributes emails between legacy SMTP (70% weight) and a new API-based delivery like Mailtrap (30% weight). ```ruby Rails.application.configure do config.action_mailer.delivery_method = :balancer # Test API delivery with 30% of emails while keeping SMTP for 70% config.action_mailer.balancer_settings = { delivery_methods: [ # Legacy SMTP delivery { method: :smtp, settings: { address: 'smtp.example.com', port: 587, user_name: ENV['SMTP_USER'], password: ENV['SMTP_PASS'], authentication: 'plain', enable_starttls_auto: true }, weight: 70 }, # New API-based delivery (requires gem like 'mailtrap') { method: :mailtrap, # Custom delivery method from gem settings: { api_token: ENV['MAILTRAP_API_TOKEN'] }, weight: 30 } ] } end ``` -------------------------------- ### Configure Action Mailer Balancer in Rails Production Environment Source: https://context7.com/mailtrap/actionmailer-balancer/llms.txt Illustrates how to integrate Action Mailer Balancer into a Rails application's production environment configuration. By setting `config.action_mailer.delivery_method` to `:balancer` and defining `config.action_mailer.balancer_settings`, all emails sent via ActionMailer will automatically use the weighted distribution logic. ```ruby # config/environments/production.rb Rails.application.configure do # Set balancer as the delivery method config.action_mailer.delivery_method = :balancer # Configure weighted distribution for gradual migration config.action_mailer.balancer_settings = { delivery_methods: [ # Old provider - 85% of traffic during migration { method: :smtp, settings: { user_name: ENV['OLD_SMTP_USER'], password: ENV['OLD_SMTP_PASS'], address: 'smtp.oldprovider.com', port: 587, authentication: 'plain' }, weight: 85 }, # New provider - 15% of traffic for testing { method: :smtp, settings: { user_name: ENV['NEW_SMTP_USER'], password: ENV['NEW_SMTP_PASS'], address: 'smtp.newprovider.com', port: 587, authentication: 'plain' }, weight: 15 } ] } # Use ActionMailer normally - balancer handles distribution # UserMailer.welcome_email(@user).deliver_later # OrderMailer.confirmation(@order).deliver_now end ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.