Class: DiscordRDA::HotReloadManager

Inherits:
Object
  • Object
show all
Defined in:
lib/discord_rda/hot_reload_manager.rb

Overview

Hot reload manager for instant bot restarts without losing state. Allows updating code without downtime.

Uses the listen gem for file system event-based watching on supported platforms, with graceful fallback to polling on unsupported platforms.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bot, logger, watch_dir: 'lib', patterns: ['*.rb']) ⇒ HotReloadManager

Initialize hot reload manager

Parameters:

  • bot (Bot)

    Bot instance

  • logger (Logger)

    Logger instance

  • watch_dir (String) (defaults to: 'lib')

    Directory to watch

  • patterns (Array<String>) (defaults to: ['*.rb'])

    File patterns to watch



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/discord_rda/hot_reload_manager.rb', line 37

def initialize(bot, logger, watch_dir: 'lib', patterns: ['*.rb'])
  @bot = bot
  @logger = logger
  @watch_dir = watch_dir
  @patterns = patterns
  @enabled = false
  @preserved_state = {}
  @watcher = nil
  @native_watching = false
  @file_mtimes = {}
  @debounce_timer = nil
end

Instance Attribute Details

#botBot (readonly)

Returns Bot instance.

Returns:

  • (Bot)

    Bot instance



12
13
14
# File 'lib/discord_rda/hot_reload_manager.rb', line 12

def bot
  @bot
end

#enabledBoolean (readonly)

Returns Whether hot reload is enabled.

Returns:

  • (Boolean)

    Whether hot reload is enabled



24
25
26
# File 'lib/discord_rda/hot_reload_manager.rb', line 24

def enabled
  @enabled
end

#loggerLogger (readonly)

Returns Logger instance.

Returns:

  • (Logger)

    Logger instance



15
16
17
# File 'lib/discord_rda/hot_reload_manager.rb', line 15

def logger
  @logger
end

#native_watchingBoolean (readonly)

Returns Whether using native file system events.

Returns:

  • (Boolean)

    Whether using native file system events



30
31
32
# File 'lib/discord_rda/hot_reload_manager.rb', line 30

def native_watching
  @native_watching
end

#patternsArray<String> (readonly)

Returns File patterns to watch.

Returns:

  • (Array<String>)

    File patterns to watch



21
22
23
# File 'lib/discord_rda/hot_reload_manager.rb', line 21

def patterns
  @patterns
end

#preserved_stateHash (readonly)

Returns State to preserve across reloads.

Returns:

  • (Hash)

    State to preserve across reloads



27
28
29
# File 'lib/discord_rda/hot_reload_manager.rb', line 27

def preserved_state
  @preserved_state
end

#watch_dirString (readonly)

Returns Watch directory.

Returns:

  • (String)

    Watch directory



18
19
20
# File 'lib/discord_rda/hot_reload_manager.rb', line 18

def watch_dir
  @watch_dir
end

Instance Method Details

#clear_statevoid

This method returns an undefined value.

Clear preserved state



87
88
89
# File 'lib/discord_rda/hot_reload_manager.rb', line 87

def clear_state
  @preserved_state.clear
end

#disablevoid

This method returns an undefined value.

Disable hot reload



62
63
64
65
66
67
68
# File 'lib/discord_rda/hot_reload_manager.rb', line 62

def disable
  return unless @enabled

  @enabled = false
  stop_watching
  @logger.info('Hot reload disabled')
end

#enablevoid

This method returns an undefined value.

Enable hot reload



52
53
54
55
56
57
58
# File 'lib/discord_rda/hot_reload_manager.rb', line 52

def enable
  return if @enabled

  @enabled = true
  start_watching
  @logger.info('Hot reload enabled', watch_dir: @watch_dir, native: @native_watching)
end

#get_preserved_state(key) ⇒ Object

Get preserved state

Parameters:

  • key (Symbol)

    State key

Returns:

  • (Object)

    State value



81
82
83
# File 'lib/discord_rda/hot_reload_manager.rb', line 81

def get_preserved_state(key)
  @preserved_state[key]
end

#preserve_state(key, value) ⇒ void

This method returns an undefined value.

Preserve state before reload

Parameters:

  • key (Symbol)

    State key

  • value (Object)

    State value



74
75
76
# File 'lib/discord_rda/hot_reload_manager.rb', line 74

def preserve_state(key, value)
  @preserved_state[key] = value
end

#reloadvoid

This method returns an undefined value.

Trigger manual reload



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/discord_rda/hot_reload_manager.rb', line 93

def reload
  @logger.info('Hot reload triggered')

  # Step 1: Preserve critical state
  preserve_bot_state

  # Step 2: Disconnect old event handlers
  @bot.event_bus.handlers.clear

  # Step 3: Reload files
  reload_files

  # Step 4: Restore state
  restore_bot_state

  # Step 5: Re-register handlers
  reinitialize_handlers

  @logger.info('Hot reload complete')
end

#statusHash

Get status

Returns:

  • (Hash)

    Status information



116
117
118
119
120
121
122
123
124
# File 'lib/discord_rda/hot_reload_manager.rb', line 116

def status
  {
    enabled: @enabled,
    watch_dir: @watch_dir,
    patterns: @patterns,
    preserved_keys: @preserved_state.keys,
    native_watching: @native_watching
  }
end