0.0
The project is in a healthy, maintained state
Simple async methods for Ruby, Ruby on Rails applications
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

Runtime

 Project Readme

AsyncMagic

AsyncMagic

AsyncMagic is a lightweight Ruby gem that makes it effortless to add asynchronous method execution to your Ruby classes. With a simple async declaration, your methods will execute in a managed thread pool, providing non-blocking operations while maintaining clean, readable code.

Inspired by Rails async methods.

!!! I believe it should be fine to use the gem in production for small apps. For now, I consider this a fun project. Please support with testing it.

Features

  • โœจ Simple async declaration for asynchronous methods
  • ๐Ÿงต Managed thread pool with configurable options
  • ๐Ÿš‚ Rails integration with ActiveRecord support
  • ๐ŸŽฏ Support for both instance and class methods
  • ๐Ÿ“ Built-in error logging
  • โšก Non-blocking execution with Future objects

Installation

Add this line to your application's Gemfile:

  gem 'async_magic'
  $ bundle install

Usage

By default, AsyncMagic will include the methods in all Objects. But you can configure it to include in specific objects (ActiveRecord models, etc.) or manually include it in your classes.

See the Configuration for more details.

class UserHeavyLogic
  async
  def send_welcome_email(user)
    # ... your code
  end

  async
  def self.batch_process(users)
    # ... your code
  end
end

# or

class UsersController < ApplicationController
  def index
    # ... your code
    log_user_activity
  end

  private

  async
  def log_user_activity
    # ... your code
  end
end

More examples

  • check if completed
  • get the result
  mailer = UserMailer.new
  future = mailer.send_welcome_email(user)
  # Check if completed
  future.completed?
  # Get the result (blocks until complete)
  result = future.value
  • initializer to configure the thread pool
  # config/initializers/async_magic.rb

  AsyncMagic.configure do |config|
    # Include in all ActiveRecord models
    config.include_in = :active_record
    # Or include globally (available everywhere)
    # config.include_in = :global
    # Or disable auto-inclusion
    # config.include_in = nil
  end
  • configure the thread pool
AsyncMagic.configure do |config|
  config.executor_options = {
    min_threads: 10, # Minimum number of threads
    max_threads: 50, # Maximum number of threads
    auto_terminate: true, # Automatically terminate threads
    idletime: 60, # Thread idle time (seconds)
    max_queue: 0, # Unlimited queue size
    fallback_policy: :caller_runs # What to do when queue is full
  }
  end
  • error handling
  class MyService
    include AsyncMagic

    async
    def risky_operation
      # If this raises an error, it will be logged
      raise "Something went wrong!"
    end
  end

The error will be logged and the future will contain the error

  future = MyService.new.risky_operation
  future.rejected? # => true
  future.reason # => #<RuntimeError: Something went wrong!>
  • manually include AsyncMagic
  class DataProcessor
    include AsyncMagic

    async
    def process_data(data)
    # Heavy processing here
    end
  end
  processor = DataProcessor.new
  future = processor.process_data(large_dataset)
  # Wait for completion with timeout
  if future.wait(5) # waits up to 5 seconds
    result = future.value
  else
    puts "Processing is taking too long!"
  end
  AsyncMagic.shutdown # Waits up to 5 seconds for completion

Code style

Just use:

  $ bundle exec standardrb
  # or
  $ bundle exec standardrb --fix

Tasks

  • extensive production testing
  • more configuration options (maybe different queues?)
  • better readme
  • consider adding delayed or recurring tasks, as part of "async" macros

Contributing

You are welcome to contribute to this gem.

License

This gem is available as open source under the terms of the MIT License.

Credits

Thanks AI to help me write this gem faster :)