Class: TopTL::Autoposter

Inherits:
Object
  • Object
show all
Defined in:
lib/toptl/autoposter.rb

Overview

Background thread that calls ‘client.post_stats` on an interval.

poster = TopTL::Autoposter.new(
  client, "mybot",
  interval_seconds: 30 * 60,
  only_on_change: true,
) { { member_count: get_user_count } }
poster.start
...
poster.stop

Designed for long-running bot processes. For one-shot cron jobs, call ‘client.post_stats` directly, or use `#post_once` below.

Defined Under Namespace

Classes: StderrLogger

Instance Method Summary collapse

Constructor Details

#initialize(client, username, interval_seconds: 30 * 60, only_on_change: true, logger: nil) { ... } ⇒ Autoposter

Returns a new instance of Autoposter.

Parameters:

  • client (TopTL::Client)
  • username (String)

    listing username to post stats for

  • interval_seconds (Integer, Float) (defaults to: 30 * 60)

    seconds between ticks (default 30 min)

  • only_on_change (Boolean) (defaults to: true)

    skip posting if stats match the last successful post (default true)

  • logger (#warn, nil) (defaults to: nil)

    any object responding to ‘warn(message)` —defaults to a stderr-backed Logger-compatible shim

Yields:

  • expected to return a Hash with any of:

    :member_count, :group_count, :channel_count, :bot_serves

Raises:

  • (ArgumentError)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/toptl/autoposter.rb', line 26

def initialize(client, username, interval_seconds: 30 * 60, only_on_change: true, logger: nil, &callback)
  raise ArgumentError, "a stats callback block is required" unless callback

  @client = client
  @username = username
  @interval = Float(interval_seconds)
  @only_on_change = only_on_change
  @callback = callback
  @logger = logger || default_logger
  @on_error = nil
  @on_post = nil
  @mutex = Mutex.new
  @stop = false
  @thread = nil
  @last = nil
end

Instance Method Details

#on_error {|Exception| ... } ⇒ Object

Set a callback invoked when a tick raises.

Yields:

  • (Exception)


52
53
54
55
# File 'lib/toptl/autoposter.rb', line 52

def on_error(&block)
  @on_error = block
  self
end

#on_post {|StatsResult| ... } ⇒ Object

Set a callback invoked after each successful post.

Yields:



45
46
47
48
# File 'lib/toptl/autoposter.rb', line 45

def on_post(&block)
  @on_post = block
  self
end

#post_onceObject

Run one tick synchronously. Useful from a cron job.



90
91
92
# File 'lib/toptl/autoposter.rb', line 90

def post_once
  tick
end

#running?Boolean

Returns:

  • (Boolean)


84
85
86
87
# File 'lib/toptl/autoposter.rb', line 84

def running?
  t = @thread
  !t.nil? && t.alive?
end

#startObject



57
58
59
60
61
62
63
64
65
66
# File 'lib/toptl/autoposter.rb', line 57

def start
  @mutex.synchronize do
    return if @thread&.alive?

    @stop = false
    @thread = Thread.new { run }
    @thread.name = "toptl-autopost:#{@username}" if @thread.respond_to?(:name=)
  end
  @thread
end

#stop(timeout: 5) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/toptl/autoposter.rb', line 68

def stop(timeout: 5)
  @mutex.synchronize do
    @stop = true
    thread = @thread
    @thread = nil
    thread
  end.tap do |t|
    next unless t

    t.wakeup if t.alive?
    t.join(timeout)
    t.kill if t.alive?
  end
  nil
end