Module: AfterMigrate
- Defined in:
- lib/after_migrate.rb,
lib/after_migrate/store.rb,
lib/after_migrate/railtie.rb,
lib/after_migrate/version.rb,
lib/after_migrate/executor.rb,
lib/after_migrate/collector.rb,
lib/after_migrate/adapters/sql.rb,
lib/after_migrate/adapters/mysql.rb,
lib/after_migrate/adapters/sqlite.rb,
lib/after_migrate/adapters/postgresql.rb
Defined Under Namespace
Modules: Collector, Executor, Mysql, Postgresql, Sql, Sqlite, Stores Classes: Configuration, Railtie
Constant Summary collapse
- VERSION =
'0.3.0'
Class Method Summary collapse
-
.affected_tables ⇒ Object
Persistent cross-migration store: schema_name => Concurrent::Set<table_name>.
- .configuration ⇒ Object
- .configure {|configuration| ... } ⇒ Object
- .log(msg) ⇒ Object
- .merge_tables(schema, table_names) ⇒ Object
- .reset! ⇒ Object
-
.run!(schema: nil) ⇒ Object
Trigger database maintenance on all collected tables, then clear the store.
- .store ⇒ Object
-
.store_degraded? ⇒ Boolean
True, when at least one store operation failed and was swallowed, so the collected table list is incomplete and maintenance coverage will be partial.
- .store_failure_count ⇒ Object
-
.with_store_rescue(operation, default: nil) ⇒ Object
A maintenance tool must never break the thing it is measuring.
Class Method Details
.affected_tables ⇒ Object
Persistent cross-migration store: schema_name => Concurrent::Set<table_name>
151 152 153 |
# File 'lib/after_migrate.rb', line 151 def affected_tables with_store_rescue('affected_tables', default: Concurrent::Map.new) { store.affected_tables } end |
.configuration ⇒ Object
138 139 140 |
# File 'lib/after_migrate.rb', line 138 def configuration @configuration ||= Configuration.new end |
.configure {|configuration| ... } ⇒ Object
142 143 144 |
# File 'lib/after_migrate.rb', line 142 def configure yield(configuration) end |
.log(msg) ⇒ Object
146 147 148 |
# File 'lib/after_migrate.rb', line 146 def log(msg) warn "[after_migrate] #{msg}" if AfterMigrate.configuration.verbose end |
.merge_tables(schema, table_names) ⇒ Object
155 156 157 |
# File 'lib/after_migrate.rb', line 155 def merge_tables(schema, table_names) with_store_rescue('merge_tables') { store.merge_tables(schema, table_names) } end |
.reset! ⇒ Object
177 178 179 180 181 182 |
# File 'lib/after_migrate.rb', line 177 def reset! with_store_rescue('reset!') { store.reset! } @store_degraded = false @store_failure_count = 0 nil end |
.run!(schema: nil) ⇒ Object
Trigger database maintenance on all collected tables, then clear the store. In multi-tenant setups call this once after all tenant migrations complete.
171 172 173 174 175 |
# File 'lib/after_migrate.rb', line 171 def run!(schema: nil) return unless configuration.enabled Executor.call(schema:) end |
.store ⇒ Object
210 211 212 213 214 |
# File 'lib/after_migrate.rb', line 210 def store @store = nil if @store_key != store_key @store_key = store_key @store ||= build_store end |
.store_degraded? ⇒ Boolean
True, when at least one store operation failed and was swallowed, so the collected table list is incomplete and maintenance coverage will be partial.
161 162 163 |
# File 'lib/after_migrate.rb', line 161 def store_degraded? @store_degraded == true end |
.store_failure_count ⇒ Object
165 166 167 |
# File 'lib/after_migrate.rb', line 165 def store_failure_count @store_failure_count.to_i end |
.with_store_rescue(operation, default: nil) ⇒ Object
A maintenance tool must never break the thing it is measuring.
Collector runs inside an sql.active_record notification subscriber, and ActiveSupport
propagates subscriber exceptions to the code that emitted the event — so a store error here
aborts the SQL statement, which aborts the migration.
Losing collected table names only means some tables miss their ANALYZE -- recoverable, and far
cheaper than a half-applied migration. Set config.raise_on_store_error = true to opt out.
The first failure logs in full; the rest are counted only, so a long migration cannot flood the log with one line per statement.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/after_migrate.rb', line 195 def with_store_rescue(operation, default: nil) yield rescue StandardError => e raise if configuration.raise_on_store_error @store_failure_count = store_failure_count + 1 unless @store_degraded @store_degraded = true log("store #{operation} failed (#{e.class}: #{e.}). Continuing without the store — " \ 'collected tables will be incomplete and some maintenance may be skipped. ' \ 'Set config.raise_on_store_error = true to make this fatal.') end default end |