module Telegram::Bot::Async

Telegram clients can perform requests in async way with any job adapter (ActiveJob by default). Using Rails you don't need any additional configuration. However you may want to enable async requests by default with `async: true` in `secrets.yml`.

telegram:
  bots:
    chat_async:
      token: secret
      async: true # enable async mode for client

Without Rails To start using async requests initialize client with `id` kwarg and make sure the client is accessible via `Teletgram.bots` in job worker. Or just use `Telegram.bots_config=` for configuration.

Being in async mode `#request` enqueues job to perform http request instead of performing it immediately. Async behavior is controlled with `#async=` writer and can be enabled/disabled for the block with `#async`:

client = Telegram::Bot::Client.new(**config, async: true)
client.send_message(message)
client.async(false) { client.send_message(other_one) }

`#async=` sets global value for all threads, while `#async(val, &block)` is thread-safe.

It can be set with custom job class or classname. By default it defines job classes inherited from ApplicationJob, which can be accessed via `.default_async_job`. You can integrate it with any other job provider by defining a class with `.perform_later(bot_id, *args)` method. See Async::Job for implemetation.

Constants

MISSING_VALUE

Used to track missing key in a hash in local variable.

Attributes

id[R]

Public Class Methods

new(*, id: nil, async: nil, **options) click to toggle source
Calls superclass method
# File lib/telegram/bot/async.rb, line 114
def initialize(*, id: nil, async: nil, **options)
  @id = id
  self.async = async
  super
end
prepare_hash(hash) click to toggle source

Transforms symbols to strings in hash values.

# File lib/telegram/bot/async.rb, line 100
def prepare_hash(hash)
  return hash unless hash.is_a?(Hash)
  hash = hash.dup
  hash.each { |key, val| hash[key] = val.to_s if val.is_a?(Symbol) }
end
prepended(base) click to toggle source
# File lib/telegram/bot/async.rb, line 95
def prepended(base)
  base.extend(ClassMethods)
end
thread_store() click to toggle source

Thread-local hash to store async config for every client.

# File lib/telegram/bot/async.rb, line 107
def thread_store
  Thread.current[:telegram_bot_async] ||= {}
end

Public Instance Methods

async(val = true) { || ... } click to toggle source

Sets async value in a thread-safe way for the block. Uses `self.class.prepare_async_val` to prepare value.

If no block is given returns previously set value or the global one, set by async=.

# File lib/telegram/bot/async.rb, line 131
def async(val = true)
  thread_key = object_id
  thread_store = Async.thread_store
  return thread_store.fetch(thread_key) { @async } unless block_given?
  begin
    old_val = thread_store.fetch(thread_key) { MISSING_VALUE }
    thread_store[thread_key] = self.class.prepare_async_val(val)
    yield
  ensure
    if MISSING_VALUE == old_val
      thread_store.delete(thread_key)
    else
      thread_store[thread_key] = old_val
    end
  end
end
async=(val) click to toggle source

Sets default async value for all threads. Uses `self.class.prepare_async_val` to prepare value.

# File lib/telegram/bot/async.rb, line 122
def async=(val)
  @async = self.class.prepare_async_val(val)
end
request(*args) click to toggle source

Uses job if async is set.

Calls superclass method
# File lib/telegram/bot/async.rb, line 149
def request(*args)
  job_class = async
  return super unless job_class
  raise 'Can not enqueue job without client id' unless id
  job_class.perform_later(id.to_s, *self.class.prepare_async_args(*args))
end