lepus-saga-active_record 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +20 -11
- data/lib/generators/lepus/saga/install/templates/create_lepus_saga_tables.rb.erb +7 -4
- data/lib/lepus/saga/active_record/execution.rb +1 -1
- data/lib/lepus/saga/active_record/version.rb +1 -1
- data/lib/lepus/saga/stores/active_record.rb +52 -8
- metadata +3 -5
- data/lib/generators/lepus/saga/dashboard_indexes/dashboard_indexes_generator.rb +0 -26
- data/lib/generators/lepus/saga/dashboard_indexes/templates/add_lepus_saga_dashboard_indexes.rb.erb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 31354b38e13fe1a57459dc0c215b05ae8c80f7437b4545269fc1c9a53dd801e1
|
|
4
|
+
data.tar.gz: 61413e70d7aebca66b160eb7e986fe94ed0d764276ecfe3c638a1a25a723e03e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5f25f07e133616a20952014f5c3541b01525fe689c99f35a4423f831096a5cecd6ee5d1526504f623bc7f9191f1b230614d65fec703d59c279cb8eff66abee2
|
|
7
|
+
data.tar.gz: 6f6e72dd03fedf4b922c9187441fa2e6a2de0f22ec6d4bfc5c79e4f2a00abde2b354d0ae08a29372c02a33a0b58b75b4a0278072a8ea49483a73f62fb68711eb
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## 0.3.1 - Unreleased
|
|
8
|
+
* Fixed: executions list in time order when their ids are not time-ordered (e.g. random UUIDv4): `list_executions` sorts and pages by (sort value, id) with `after`, `executions_for_resource` and `recent_first` order by started_at, then id
|
|
9
|
+
* Added: the `duration_ms` bigint column, the `sort`/`direction`/`after` options of `list_executions` (keyset paging in at most two queries that start the `(column, id)` index at the cursor, executions without a duration last), the `finished_from`/`finished_to` filters and `executed_steps` in one query
|
|
10
|
+
* Changed: the `from`/`to` filters and the series' starts use started_at; `lepus-saga ~> 0.3.1` is required
|
|
11
|
+
* Changed: dashboard indexes folded into the install migration (pre-release): `lepus:saga:install` indexes `saga_executions (started_at, id)`, `(duration_ms, id)`, `(finished_at)`, `(saga_name, started_at)`, `(status, started_at)`, `(partition, started_at)` and the resource index on `(resource_type, resource_id, started_at)`; the created_at indexes and the `lepus:saga:dashboard_indexes` generator are gone
|
|
12
|
+
|
|
7
13
|
## 0.3.0 - Unreleased
|
|
8
14
|
* Added: brand mark and README logo
|
|
9
15
|
* Added: `Lepus::Saga::Stores::ActiveRecord`, selected with `Lepus::Saga.configure { |c| c.store = :active_record }`
|
data/README.md
CHANGED
|
@@ -22,7 +22,7 @@ bin/rails generate lepus:saga:install
|
|
|
22
22
|
bin/rails db:migrate
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The generator writes one migration that creates both tables. Ids are UUIDv7 strings generated in Ruby, the context columns are `json` and `failure_reason` is `text` (a step's error message can outgrow `VARCHAR(255)`, and MySQL/MariaDB strict mode would reject the write that fails the saga).
|
|
25
|
+
The generator writes one migration that creates both tables and their indexes. Ids are UUIDv7 strings generated in Ruby, the context columns are `json` and `failure_reason` is `text` (a step's error message can outgrow `VARCHAR(255)`, and MySQL/MariaDB strict mode would reject the write that fails the saga). `saga_executions.duration_ms` is a `bigint` the engine writes when an execution ends. Besides the resource, progress and attempt indexes the engine uses, it indexes what the console sorts and filters on: `saga_executions (started_at, id)`, `(duration_ms, id)`, `(finished_at)`, `(saga_name, started_at)`, `(status, started_at)` and `(partition, started_at)`, and `saga_step_attempts (started_at)` and `(error_class, started_at)`.
|
|
26
26
|
|
|
27
27
|
```ruby
|
|
28
28
|
# config/initializers/lepus_saga.rb
|
|
@@ -68,11 +68,14 @@ Lepus::Saga::ActiveRecord::Execution.where.not(id: pinned_ids).prune(finished_be
|
|
|
68
68
|
| `with_locked_execution(id)` | `transaction { Execution.lock.find_by(id:) }`, one query |
|
|
69
69
|
| `increment_resume_count` | `update_counters(id, resume_count: 1, touch: true)`, then reads the stored value back |
|
|
70
70
|
| `create_step_attempt` | `create!`; `ActiveRecord::RecordNotUnique` from `idx_saga_step_attempts_dedup` becomes `Lepus::Saga::DuplicateAttemptError` |
|
|
71
|
-
| `stalled_executions(before:)` | `in_progress.where(last_progress_at: ...before).order(:last_progress_at)` |
|
|
71
|
+
| `stalled_executions(before:)` | `in_progress.where(last_progress_at: ...before).order(:last_progress_at, :id)` |
|
|
72
|
+
| `executions_for_resource` | `for_resource(type, id).recent_first`: `ORDER BY started_at DESC, id DESC` on the resource index |
|
|
72
73
|
| attempt queries | `where(saga_execution_id:, step_name:, direction:, epoch:)` plus `count`/`exists?` |
|
|
73
|
-
| `list_executions` | Filters on the executions table, `
|
|
74
|
+
| `list_executions` | Filters on the executions table, ordered by `(started_at, id)`, `(duration_ms, id)` or `(finished_at, id)` in the requested direction. Paging is keyset: rows after `after` compare against its stored value in a subquery (`col <= (SELECT col ... WHERE id = ?) AND (col < (SELECT ...) OR id < ?)` descending, `>=` and `>` ascending); the bare bound lets the `(column, id)` index start at the cursor instead of reading every row before it. For a nullable sort it runs at most two queries, the rows with a value and then, when the page is not full, the rows without one by id, so both use the `(column, id)` index and nulls come last either way; the resource search is `LOWER(column) LIKE ? ESCAPE '!'`; the error filters are `id IN (SELECT saga_execution_id FROM saga_step_attempts WHERE status = 'failed' ...)` |
|
|
74
75
|
| `count_executions` | `group(...).count`; grouping by partition also groups by saga name to resolve executions without one |
|
|
75
|
-
| `
|
|
76
|
+
| `finished_executions` | Base's: `count_executions` grouped by saga and status over `finished_from`/`finished_to`, then one `list_executions(sort: :finished_at)` per saga, on the `finished_at` index |
|
|
77
|
+
| `executed_steps` | One `SELECT DISTINCT saga_execution_id, step_name FROM saga_step_attempts WHERE saga_execution_id IN (...) AND direction = 'execute'` for every execution `/api/recent` lists |
|
|
78
|
+
| `execution_series` | Plucks `started_at`, and `finished_at` and `status` of terminal executions, newest first and at most `max_rows` + 1; buckets them in Ruby |
|
|
76
79
|
| `step_latency` | Joins attempts to executions and plucks the newest `max_rows` + 1 durations; percentiles in Ruby |
|
|
77
80
|
| `failure_summary` | `GROUP BY error_class, saga_name, step_name` with `COUNT(*)` and `COUNT(DISTINCT saga_execution_id)`, ordered by `COUNT(*)` and `MAX(finished_at)`, then one query per group for its latest failure |
|
|
78
81
|
| `saga_names` | `distinct.order(:saga_name).pluck(:saga_name)` |
|
|
@@ -89,16 +92,23 @@ The `belongs_to :execution` of a step attempt is optional, because the foreign k
|
|
|
89
92
|
|
|
90
93
|
## Existing tables
|
|
91
94
|
|
|
92
|
-
Tables created by hand or before the generator (PostgreSQL `uuid` ids with `gen_random_uuid()` defaults, `jsonb` context, a `lock_version` column) work unchanged: the models set UUIDv7 ids before insert, read `jsonb` through the `json` attribute type and ignore `lock_version`.
|
|
95
|
+
Tables created by hand or before the generator (PostgreSQL `uuid` ids with `gen_random_uuid()` defaults, `jsonb` context, a `lock_version` column) work unchanged: the models set UUIDv7 ids before insert, read `jsonb` through the `json` attribute type and ignore `lock_version`. Rows written with ids that are not time-ordered (e.g. random UUIDv4) list in time order, since the store sorts by started_at (or duration) and only breaks ties by id.
|
|
93
96
|
|
|
94
|
-
|
|
97
|
+
Such tables, and tables created by the 0.3.0 install generator, lack the `duration_ms` column and some of the indexes the install migration creates. Add them in a migration of your own; `if_not_exists: true` skips the indexes a table already has:
|
|
95
98
|
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
```ruby
|
|
100
|
+
add_column :saga_executions, :duration_ms, :bigint, if_not_exists: true
|
|
101
|
+
add_index :saga_executions, [:started_at, :id], if_not_exists: true
|
|
102
|
+
add_index :saga_executions, [:duration_ms, :id], if_not_exists: true
|
|
103
|
+
add_index :saga_executions, :finished_at, if_not_exists: true
|
|
104
|
+
add_index :saga_executions, [:saga_name, :started_at], if_not_exists: true
|
|
105
|
+
add_index :saga_executions, [:status, :started_at], if_not_exists: true
|
|
106
|
+
add_index :saga_executions, [:partition, :started_at], if_not_exists: true
|
|
107
|
+
add_index :saga_step_attempts, :started_at, if_not_exists: true
|
|
108
|
+
add_index :saga_step_attempts, [:error_class, :started_at], if_not_exists: true
|
|
99
109
|
```
|
|
100
110
|
|
|
101
|
-
|
|
111
|
+
and backfill the duration of finished executions, for example with `Lepus::Saga::ActiveRecord::Execution.where.not(finished_at: nil).find_each { |execution| execution.update_columns(duration_ms: ((execution.finished_at - execution.started_at) * 1000).round) }`. The `created_at` indexes of 0.3.0 (`[:saga_name, :created_at]`, `[:status, :created_at]`, `[:partition, :created_at]`) are no longer used and can be dropped.
|
|
102
112
|
|
|
103
113
|
## Architecture
|
|
104
114
|
|
|
@@ -112,7 +122,6 @@ StepAttemptBehaviour <─── Lepus::Saga::ActiveRecord::StepAttempt
|
|
|
112
122
|
"a lepus saga engine" ───> (contract and full engine on every database)
|
|
113
123
|
"a lepus saga query store" ───>
|
|
114
124
|
lib/generators/lepus/saga/install
|
|
115
|
-
lib/generators/lepus/saga/dashboard_indexes
|
|
116
125
|
```
|
|
117
126
|
|
|
118
127
|
This gem is also the reference for writing another adapter (Sequel, ROM, a key-value store):
|
|
@@ -14,19 +14,22 @@ class CreateLepusSagaTables < ActiveRecord::Migration<%= migration_version %>
|
|
|
14
14
|
t.string :partition
|
|
15
15
|
t.datetime :started_at, null: false
|
|
16
16
|
t.datetime :finished_at
|
|
17
|
+
t.bigint :duration_ms
|
|
17
18
|
t.datetime :last_progress_at, null: false
|
|
18
19
|
t.integer :resume_count, null: false, default: 0
|
|
19
20
|
t.timestamps
|
|
20
21
|
end
|
|
21
|
-
add_index :saga_executions, [:resource_type, :resource_id, :
|
|
22
|
+
add_index :saga_executions, [:resource_type, :resource_id, :started_at],
|
|
22
23
|
name: "idx_saga_executions_on_resource"
|
|
23
24
|
add_index :saga_executions, [:status, :updated_at]
|
|
24
25
|
add_index :saga_executions, [:status, :last_progress_at],
|
|
25
26
|
name: "index_saga_executions_on_status_and_progress"
|
|
26
|
-
add_index :saga_executions, [:
|
|
27
|
-
add_index :saga_executions, [:
|
|
28
|
-
add_index :saga_executions, [:status, :created_at]
|
|
27
|
+
add_index :saga_executions, [:started_at, :id]
|
|
28
|
+
add_index :saga_executions, [:duration_ms, :id]
|
|
29
29
|
add_index :saga_executions, :finished_at
|
|
30
|
+
add_index :saga_executions, [:partition, :started_at]
|
|
31
|
+
add_index :saga_executions, [:saga_name, :started_at]
|
|
32
|
+
add_index :saga_executions, [:status, :started_at]
|
|
30
33
|
|
|
31
34
|
create_table :saga_step_attempts, id: :string, limit: 36 do |t|
|
|
32
35
|
t.references :saga_execution, type: :string, limit: 36, null: false, foreign_key: true
|
|
@@ -30,7 +30,7 @@ module Lepus
|
|
|
30
30
|
scope :for_resource, ->(type, id) { where(resource_type: type, resource_id: id) }
|
|
31
31
|
scope :in_progress, -> { where(status: IN_PROGRESS_STATUSES) }
|
|
32
32
|
scope :completed, -> { where(status: "completed") }
|
|
33
|
-
scope :recent_first, -> { order(
|
|
33
|
+
scope :recent_first, -> { order(started_at: :desc, id: :desc) }
|
|
34
34
|
# Deliberately not `updated_at`: a re-publish, a lock or an attempt
|
|
35
35
|
# opened and abandoned all touch the row while the cursor stands
|
|
36
36
|
# still, so a wedged execution would keep resetting its own stall clock.
|
|
@@ -61,7 +61,7 @@ module Lepus
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def stalled_executions(before:)
|
|
64
|
-
execution_class.in_progress.where(last_progress_at: ...before).order(:last_progress_at)
|
|
64
|
+
execution_class.in_progress.where(last_progress_at: ...before).order(:last_progress_at, :id)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def executions_for_resource(resource_type, resource_id)
|
|
@@ -83,6 +83,15 @@ module Lepus
|
|
|
83
83
|
attempts_of(execution).chronological
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
+
def executed_steps(executions)
|
|
87
|
+
steps = executions.to_h { |execution| [execution.id, []] }
|
|
88
|
+
return steps if steps.empty?
|
|
89
|
+
|
|
90
|
+
step_attempt_class.where(saga_execution_id: steps.keys, direction: "execute").distinct
|
|
91
|
+
.pluck(:saga_execution_id, :step_name).each { |id, step| steps[id] << step }
|
|
92
|
+
steps
|
|
93
|
+
end
|
|
94
|
+
|
|
86
95
|
def count_step_attempts(execution, step_name:, direction:, epoch:)
|
|
87
96
|
attempts_of(execution).where(step_name: step_name, direction: direction, epoch: epoch).count
|
|
88
97
|
end
|
|
@@ -104,10 +113,29 @@ module Lepus
|
|
|
104
113
|
|
|
105
114
|
def queries? = true
|
|
106
115
|
|
|
107
|
-
|
|
116
|
+
# Keyset paging in up to two index-friendly queries: the executions
|
|
117
|
+
# with a value in (value, id) order, then those without one by id.
|
|
118
|
+
def list_executions(sort: :started_at, direction: :desc, after: nil, limit: 50, **filters)
|
|
119
|
+
column, descending, nullable = list_order(sort, direction, filters)
|
|
108
120
|
scope = matching_executions(**filters)
|
|
109
|
-
|
|
110
|
-
|
|
121
|
+
order = descending ? :desc : :asc
|
|
122
|
+
if after
|
|
123
|
+
cursor = execution_class.where(id: after).pluck(:id, column).first
|
|
124
|
+
return [] unless cursor
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
in_nulls = cursor && cursor.last.nil?
|
|
128
|
+
rows = []
|
|
129
|
+
unless in_nulls
|
|
130
|
+
valued = nullable ? scope.where.not(column => nil) : scope
|
|
131
|
+
valued = valued.where(beyond(column, after, descending)) if cursor
|
|
132
|
+
rows = valued.order(column => order, :id => order).limit(limit).to_a
|
|
133
|
+
end
|
|
134
|
+
return rows unless nullable && rows.size < limit
|
|
135
|
+
|
|
136
|
+
unvalued = scope.where(column => nil)
|
|
137
|
+
unvalued = unvalued.where(execution_class.arel_table[:id].public_send(descending ? :lt : :gt, after)) if in_nulls
|
|
138
|
+
rows + unvalued.order(id: order).limit(limit - rows.size).to_a
|
|
111
139
|
end
|
|
112
140
|
|
|
113
141
|
def count_executions(group_by:, **filters)
|
|
@@ -122,7 +150,7 @@ module Lepus
|
|
|
122
150
|
seconds = series_bucket(from, to, bucket)
|
|
123
151
|
scope = matching_executions(saga_name: saga_name)
|
|
124
152
|
started, started_truncated = take_rows(
|
|
125
|
-
scope.where(
|
|
153
|
+
scope.where(started_at: from...to).order(started_at: :desc).limit(max_rows + 1).pluck(:started_at),
|
|
126
154
|
max_rows
|
|
127
155
|
)
|
|
128
156
|
finished, finished_truncated = take_rows(
|
|
@@ -176,8 +204,22 @@ module Lepus
|
|
|
176
204
|
step_attempt_class.where(saga_execution_id: execution.id)
|
|
177
205
|
end
|
|
178
206
|
|
|
207
|
+
# Rows strictly after the execution `after` in (column, id) order,
|
|
208
|
+
# comparing against its stored value in a subquery so no precision is
|
|
209
|
+
# lost on the way through Ruby. The bare bound on the column lets the
|
|
210
|
+
# (column, id) index start at the cursor instead of filtering every
|
|
211
|
+
# row before it.
|
|
212
|
+
def beyond(column, after, descending)
|
|
213
|
+
table = execution_class.arel_table
|
|
214
|
+
value = execution_class.where(id: after).select(column).arel
|
|
215
|
+
strict, bound = descending ? %i[lt lteq] : %i[gt gteq]
|
|
216
|
+
table[column].public_send(bound, value)
|
|
217
|
+
.and(table[column].public_send(strict, value).or(table[:id].public_send(strict, after)))
|
|
218
|
+
end
|
|
219
|
+
|
|
179
220
|
def matching_executions(saga_name: nil, status: nil, current_step: nil, partition: nil, resource: nil, from: nil, to: nil,
|
|
180
|
-
progress_from: nil, progress_to: nil,
|
|
221
|
+
progress_from: nil, progress_to: nil, finished_from: nil, finished_to: nil, error_class: nil, error_step: nil, error_from: nil,
|
|
222
|
+
error_to: nil)
|
|
181
223
|
sagas = filter_values(saga_name)
|
|
182
224
|
statuses = filter_values(status)
|
|
183
225
|
steps = filter_values(current_step)
|
|
@@ -185,10 +227,12 @@ module Lepus
|
|
|
185
227
|
scope = scope.where(saga_name: sagas) if sagas
|
|
186
228
|
scope = scope.where(status: statuses) if statuses
|
|
187
229
|
scope = scope.where(current_step: steps) if steps
|
|
188
|
-
scope = scope.where(
|
|
189
|
-
scope = scope.where(
|
|
230
|
+
scope = scope.where(started_at: from..) if from
|
|
231
|
+
scope = scope.where(started_at: ...to) if to
|
|
190
232
|
scope = scope.where(last_progress_at: progress_from..) if progress_from
|
|
191
233
|
scope = scope.where(last_progress_at: ...progress_to) if progress_to
|
|
234
|
+
scope = scope.where(finished_at: finished_from..) if finished_from
|
|
235
|
+
scope = scope.where(finished_at: ...finished_to) if finished_to
|
|
192
236
|
failing = failed_attempts(filter_values(error_class), filter_values(error_step), error_from, error_to)
|
|
193
237
|
scope = scope.where(id: failing.select(:saga_execution_id)) if failing
|
|
194
238
|
scope = scope.and(in_partition(partition.to_s)) if partition.present?
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lepus-saga-active_record
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marcos G. Zimmermann
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.3.
|
|
18
|
+
version: 0.3.1
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.3.
|
|
25
|
+
version: 0.3.1
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: activerecord
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -199,8 +199,6 @@ files:
|
|
|
199
199
|
- docs/brand/mark-small-on-light.svg
|
|
200
200
|
- docs/brand/mark-small.svg
|
|
201
201
|
- docs/brand/mark.svg
|
|
202
|
-
- lib/generators/lepus/saga/dashboard_indexes/dashboard_indexes_generator.rb
|
|
203
|
-
- lib/generators/lepus/saga/dashboard_indexes/templates/add_lepus_saga_dashboard_indexes.rb.erb
|
|
204
202
|
- lib/generators/lepus/saga/install/install_generator.rb
|
|
205
203
|
- lib/generators/lepus/saga/install/templates/create_lepus_saga_tables.rb.erb
|
|
206
204
|
- lib/lepus/saga/active_record.rb
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "rails/generators"
|
|
4
|
-
require "rails/generators/active_record"
|
|
5
|
-
|
|
6
|
-
module Lepus
|
|
7
|
-
module Saga
|
|
8
|
-
class DashboardIndexesGenerator < Rails::Generators::Base
|
|
9
|
-
include ::ActiveRecord::Generators::Migration
|
|
10
|
-
|
|
11
|
-
source_root File.expand_path("templates", __dir__)
|
|
12
|
-
|
|
13
|
-
desc "Adds the indexes the store's query methods use to saga tables created before they were in lepus:saga:install"
|
|
14
|
-
|
|
15
|
-
def create_migration_file
|
|
16
|
-
migration_template "add_lepus_saga_dashboard_indexes.rb.erb", File.join(db_migrate_path, "add_lepus_saga_dashboard_indexes.rb")
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
|
|
21
|
-
def migration_version
|
|
22
|
-
"[#{::ActiveRecord::VERSION::MAJOR}.#{::ActiveRecord::VERSION::MINOR}]"
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
data/lib/generators/lepus/saga/dashboard_indexes/templates/add_lepus_saga_dashboard_indexes.rb.erb
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
class AddLepusSagaDashboardIndexes < ActiveRecord::Migration<%= migration_version %>
|
|
2
|
-
def up
|
|
3
|
-
add_index :saga_executions, [:saga_name, :created_at], if_not_exists: true
|
|
4
|
-
add_index :saga_executions, [:status, :created_at], if_not_exists: true
|
|
5
|
-
add_index :saga_executions, :finished_at, if_not_exists: true
|
|
6
|
-
add_index :saga_step_attempts, :started_at, if_not_exists: true
|
|
7
|
-
add_index :saga_step_attempts, [:error_class, :started_at], if_not_exists: true
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def down
|
|
11
|
-
remove_index :saga_step_attempts, [:error_class, :started_at], if_exists: true
|
|
12
|
-
remove_index :saga_step_attempts, :started_at, if_exists: true
|
|
13
|
-
remove_index :saga_executions, :finished_at, if_exists: true
|
|
14
|
-
remove_index :saga_executions, [:status, :created_at], if_exists: true
|
|
15
|
-
remove_index :saga_executions, [:saga_name, :created_at], if_exists: true
|
|
16
|
-
end
|
|
17
|
-
end
|