good_job 3.0.2 → 3.3.0
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 +52 -1
- data/README.md +35 -31
- data/app/assets/good_job/modules/application.js +2 -0
- data/app/assets/good_job/modules/popovers.js +7 -0
- data/app/assets/good_job/style.css +4 -0
- data/app/controllers/good_job/jobs_controller.rb +1 -1
- data/app/helpers/good_job/application_helper.rb +2 -2
- data/app/views/good_job/cron_entries/index.html.erb +60 -57
- data/app/views/good_job/jobs/_executions.erb +31 -28
- data/app/views/good_job/jobs/_table.erb +138 -109
- data/app/views/good_job/jobs/show.html.erb +41 -32
- data/app/views/good_job/processes/index.html.erb +60 -32
- data/app/views/good_job/shared/_filter.erb +1 -1
- data/app/views/good_job/shared/_navbar.erb +15 -3
- data/app/views/good_job/shared/icons/_dots.html.erb +3 -0
- data/app/views/good_job/shared/icons/_info.html.erb +4 -0
- data/config/locales/en.yml +19 -0
- data/config/locales/es.yml +19 -0
- data/config/locales/nl.yml +19 -0
- data/config/locales/ru.yml +19 -0
- data/lib/generators/good_job/templates/install/migrations/create_good_jobs.rb.erb +4 -4
- data/lib/generators/good_job/templates/update/migrations/01_create_good_jobs.rb.erb +4 -4
- data/lib/good_job/daemon.rb +2 -2
- data/lib/good_job/job_performer.rb +1 -1
- data/lib/good_job/version.rb +1 -1
- data/lib/models/good_job/cron_entry.rb +4 -2
- data/lib/models/good_job/execution.rb +63 -40
- data/lib/models/good_job/job.rb +32 -7
- data/lib/models/good_job/process.rb +2 -0
- data/lib/models/good_job/reportable.rb +43 -0
- metadata +6 -2
| @@ -1,122 +1,151 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
                        < | 
| 12 | 
            -
             | 
| 13 | 
            -
                        <th>Executions</th>
         | 
| 14 | 
            -
                        <th>Error</th>
         | 
| 15 | 
            -
                        <th>
         | 
| 16 | 
            -
                          ActiveJob Params 
         | 
| 17 | 
            -
                          <%= tag.button "Toggle", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
         | 
| 18 | 
            -
                                         data: { bs_toggle: "collapse", bs_target: ".job-params" },
         | 
| 19 | 
            -
                                         aria: { expanded: false, controls: jobs.map { |job| "##{dom_id(job, "params")}" }.join(" ") }
         | 
| 20 | 
            -
                          %>
         | 
| 21 | 
            -
                        </th>
         | 
| 22 | 
            -
                        <th>
         | 
| 23 | 
            -
                          Actions<br>
         | 
| 1 | 
            +
            <%= form_with(url: mass_update_jobs_path(filter.to_params), method: :put, local: true, data: { "checkbox-toggle": "job_ids" }) do |form| %>
         | 
| 2 | 
            +
            <div class="my-3 card" data-gj-poll-replace id="jobs-table">
         | 
| 3 | 
            +
              <div class="list-group list-group-flush text-nowrap table-jobs" role="table">
         | 
| 4 | 
            +
                <header class="list-group-item bg-light">
         | 
| 5 | 
            +
                  <div class="row small text-muted text-uppercase align-items-center">
         | 
| 6 | 
            +
                    <div class="col-auto">
         | 
| 7 | 
            +
                      <%= check_box_tag('toggle_job_ids', "1", false, data: { "checkbox-toggle-all": "job_ids" }) %>
         | 
| 8 | 
            +
                    </div>
         | 
| 9 | 
            +
                    <div class="col-4">
         | 
| 10 | 
            +
                      <%= form.button type: 'submit', name: 'mass_action', value: 'reschedule', class: 'btn btn-sm btn-outline-secondary', title: "Reschedule all", data: { confirm: "Are you sure you want to reschedule the selected jobs?", disable: true } do %>
         | 
| 11 | 
            +
                        <span class="me-1"><%= render_icon "skip_forward" %></span> Reschedule
         | 
| 12 | 
            +
                      <% end %>
         | 
| 24 13 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
                            <% end %>
         | 
| 14 | 
            +
                      <%= form.button type: 'submit', name: 'mass_action', value: 'retry', class: 'btn btn-sm btn-outline-secondary', title: "Retry all", data: { confirm: "Are you sure you want to retry the selected jobs?", disable: true } do %>
         | 
| 15 | 
            +
                        <span class="me-1"><%= render_icon "arrow_clockwise" %></span> Retry
         | 
| 16 | 
            +
                      <% end %>
         | 
| 29 17 |  | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 18 | 
            +
                      <div class="btn-group" role="group">
         | 
| 19 | 
            +
                        <%= form.button type: 'submit', name: 'mass_action', value: 'discard', class: 'btn btn-sm btn-outline-secondary', title: "Discard all", data: { confirm: "Are you usure you want to discard the selected jobs?", disable: true } do %>
         | 
| 20 | 
            +
                          <span class="me-1"><%= render_icon "stop" %></span> Discard
         | 
| 21 | 
            +
                        <% end %>
         | 
| 22 | 
            +
                        <button id="destroy-dropdown-toggle" type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
         | 
| 23 | 
            +
                          <span class="visually-hidden">Toggle Actions</span>
         | 
| 24 | 
            +
                        </button>
         | 
| 25 | 
            +
                        <div class="dropdown-menu" aria-labelledby="destroy-dropdown-toggle">
         | 
| 26 | 
            +
                          <li>
         | 
| 27 | 
            +
                            <%= form.button type: 'submit', name: 'mass_action', value: 'destroy', class: 'btn', title: "Destroy all", data: { confirm: "Are you sure you want to destroy the selected jobs?", disable: true } do %>
         | 
| 28 | 
            +
                              <span class="me-1"><%= render_icon "trash" %></span> Destroy
         | 
| 32 29 | 
             
                            <% end %>
         | 
| 30 | 
            +
                          </li>
         | 
| 31 | 
            +
                        </div>
         | 
| 32 | 
            +
                      </div>
         | 
| 33 33 |  | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 34 | 
            +
                    </div>
         | 
| 35 | 
            +
                    <div class="col-1">Queue</div>
         | 
| 36 | 
            +
                    <div class="col-1">Priority</div>
         | 
| 37 | 
            +
                    <div class="col-1 text-end">Attempts</div>
         | 
| 38 | 
            +
                    <div class="col text-end">
         | 
| 39 | 
            +
                      <%= tag.button type: "button", class: "btn btn-sm text-muted", role: "button",
         | 
| 40 | 
            +
                              data: { bs_toggle: "collapse", bs_target: ".job-params" },
         | 
| 41 | 
            +
                              aria: { expanded: false, controls: jobs.map { |job| "##{dom_id(job, "params")}" }.join(" ") } do %>
         | 
| 42 | 
            +
                          <%= render_icon "info" %>
         | 
| 43 | 
            +
                          <span class="visually-hidden">Inspect</span>
         | 
| 44 | 
            +
                      <% end %>
         | 
| 45 | 
            +
                    </div>
         | 
| 46 | 
            +
                  </div>
         | 
| 47 | 
            +
                </header>
         | 
| 48 | 
            +
                <label role="row" class="list-group-item list-group-item-warning list-group-item-action py-3 d-none" data-checkbox-toggle-show="job_ids">
         | 
| 49 | 
            +
                  <div class="row">
         | 
| 50 | 
            +
                    <div class="col-auto">
         | 
| 51 | 
            +
                      <%= check_box_tag "all_job_ids", 1, false, disabled: true, data: { "checkbox-toggle-show": "job_ids"} %>
         | 
| 52 | 
            +
                    </div>
         | 
| 53 | 
            +
                    <div class="col-auto">
         | 
| 54 | 
            +
                      Apply to all <%= filter.filtered_count %> <%= "job".pluralize(filter.filtered_count) %>.
         | 
| 55 | 
            +
                    </div>
         | 
| 56 | 
            +
                  </div>
         | 
| 57 | 
            +
                </label>
         | 
| 37 58 |  | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
                         | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
                        < | 
| 46 | 
            -
                           | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
                         | 
| 56 | 
            -
                           | 
| 57 | 
            -
                             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
                             | 
| 63 | 
            -
             | 
| 64 | 
            -
                            < | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
                              <%=  | 
| 75 | 
            -
             | 
| 76 | 
            -
                             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
                                   | 
| 82 | 
            -
             | 
| 83 | 
            -
                                  <button class="btn btn-sm btn-outline-secondary" disabled><%= render_icon "skip_forward" %></button>
         | 
| 59 | 
            +
                <% if jobs.present? %>
         | 
| 60 | 
            +
                  <% jobs.each do |job| %>
         | 
| 61 | 
            +
                    <%= label_tag dom_id(job, :checkbox), id: dom_id(job), role: "row", class: "list-group-item list-group-item-action py-3" do %>
         | 
| 62 | 
            +
                      <div class="row align-items-center">
         | 
| 63 | 
            +
                        <div class="col-auto">
         | 
| 64 | 
            +
                          <%= check_box_tag 'job_ids[]', job.id, false, id: dom_id(job, :checkbox), data: { "checkbox-toggle-each": "job_ids" } %>
         | 
| 65 | 
            +
                        </div>
         | 
| 66 | 
            +
                        <div class="col-4">
         | 
| 67 | 
            +
                          <%= tag.code link_to(job.id, job_path(job), class: "small text-muted text-decoration-none") %>
         | 
| 68 | 
            +
                          <%= tag.h5 tag.code(link_to(job.job_class, job_path(job), class: "text-reset text-decoration-none")), class: "text-reset mb-0" %>
         | 
| 69 | 
            +
                        </div>
         | 
| 70 | 
            +
                        <div class="col-1">
         | 
| 71 | 
            +
                          <span class="badge bg-primary bg-opacity-25 text-dark font-monospace"><%= job.queue_name %></span>
         | 
| 72 | 
            +
                        </div>
         | 
| 73 | 
            +
                        <div class="col-1 small text-center">
         | 
| 74 | 
            +
                          <span class="font-monospace fw-bold"><%= job.priority %></span>
         | 
| 75 | 
            +
                        </div>
         | 
| 76 | 
            +
                        <div class="col-1 text-center">
         | 
| 77 | 
            +
                          <% if job.executions_count > 0 && job.status != :finished %>
         | 
| 78 | 
            +
                            <%= tag.span job.executions_count, class: "badge rounded-pill bg-danger", data: {
         | 
| 79 | 
            +
                                  bs_toggle: "popover",
         | 
| 80 | 
            +
                                  bs_trigger: "hover focus click",
         | 
| 81 | 
            +
                                  bs_placement: "bottom",
         | 
| 82 | 
            +
                                  bs_content: job.recent_error
         | 
| 83 | 
            +
                            } %>
         | 
| 84 | 
            +
                          <% else %>
         | 
| 85 | 
            +
                            <span class="badge bg-secondary bg-opacity-50 rounded-pill"><%= job.executions_count %></span>
         | 
| 86 | 
            +
                          <% end %>
         | 
| 87 | 
            +
                        </div>
         | 
| 88 | 
            +
                        <div class="col d-flex gap-3 align-items-center justify-content-end">
         | 
| 89 | 
            +
                          <%= tag.span relative_time(job.last_status_at), class: "small" %>
         | 
| 90 | 
            +
                          <%= status_badge job.status %>
         | 
| 91 | 
            +
                        </div>
         | 
| 92 | 
            +
                        <div class="col-auto">
         | 
| 93 | 
            +
                          <div class="dropdown float-end">
         | 
| 94 | 
            +
                            <button class="d-flex align-items-center btn btn-sm" type="button" id="<%= dom_id(job, :actions) %>" data-bs-toggle="dropdown" aria-expanded="false">
         | 
| 95 | 
            +
                              <%= render "good_job/shared/icons/dots" %>
         | 
| 96 | 
            +
                              <span class="visually-hidden">Actions</span>
         | 
| 97 | 
            +
                            </button>
         | 
| 98 | 
            +
                            <ul class="dropdown-menu shadow" aria-labelledby="<%= dom_id(job, :actions) %>">
         | 
| 99 | 
            +
                              <li>
         | 
| 100 | 
            +
                                <% job_reschedulable = job.status.in? [:scheduled, :retried, :queued] %>
         | 
| 101 | 
            +
                                <%= link_to reschedule_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_reschedulable}", title: "Reschedule job", data: { confirm: "Confirm reschedule", disable: true } do %>
         | 
| 102 | 
            +
                                  <%= render "good_job/shared/icons/skip_forward" %>
         | 
| 103 | 
            +
                                  Reschedule
         | 
| 84 104 | 
             
                                <% end %>
         | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
                                   | 
| 90 | 
            -
             | 
| 91 | 
            -
                                  <button class="btn btn-sm btn-outline-secondary" disabled><%= render_icon "stop" %></button>
         | 
| 105 | 
            +
                              </li>
         | 
| 106 | 
            +
                              <li>
         | 
| 107 | 
            +
                                <% job_discardable = job.status.in? [:scheduled, :retried, :queued] %>
         | 
| 108 | 
            +
                                <%= link_to discard_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_discardable}", title: "Discard job", data: { confirm: "Confirm discard", disable: true } do %>
         | 
| 109 | 
            +
                                  <%= render "good_job/shared/icons/stop" %>
         | 
| 110 | 
            +
                                  Discard
         | 
| 92 111 | 
             
                                <% end %>
         | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 97 | 
            -
                                   | 
| 98 | 
            -
                                <%  | 
| 99 | 
            -
             | 
| 112 | 
            +
                              </li>
         | 
| 113 | 
            +
                              <li>
         | 
| 114 | 
            +
                                <%= link_to retry_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job.status == :discarded}", title: "Retry job", data: { confirm: "Confirm retry", disable: true } do %>
         | 
| 115 | 
            +
                                  <%= render "good_job/shared/icons/arrow_clockwise" %>
         | 
| 116 | 
            +
                                  Retry
         | 
| 117 | 
            +
                                <% end %>
         | 
| 118 | 
            +
                              </li>
         | 
| 119 | 
            +
                              <li>
         | 
| 120 | 
            +
                                <%= link_to job_path(job.id), method: :delete, class: "dropdown-item #{'disabled' unless job.status.in? [:discarded, :finished]}", title: "Destroy job", data: { confirm: "Confirm destroy", disable: true } do %>
         | 
| 121 | 
            +
                                  <%= render_icon "trash" %>
         | 
| 122 | 
            +
                                  Destroy
         | 
| 100 123 | 
             
                                <% end %>
         | 
| 124 | 
            +
                              </li>
         | 
| 101 125 |  | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
                                   | 
| 106 | 
            -
             | 
| 107 | 
            -
                                   | 
| 126 | 
            +
                              <li>
         | 
| 127 | 
            +
                                <%= link_to "##{dom_id(job, 'params')}",
         | 
| 128 | 
            +
                                  class: "dropdown-item",
         | 
| 129 | 
            +
                                  data: { bs_toggle: "collapse" },
         | 
| 130 | 
            +
                                  aria: { expanded: false, controls: dom_id(job, "params") } do %>
         | 
| 131 | 
            +
                                  <%= render_icon "info" %>
         | 
| 132 | 
            +
                                  Inspect
         | 
| 108 133 | 
             
                                <% end %>
         | 
| 109 | 
            -
                              </ | 
| 110 | 
            -
                            </ | 
| 111 | 
            -
                          </ | 
| 112 | 
            -
                         | 
| 113 | 
            -
                       | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 134 | 
            +
                              </li>
         | 
| 135 | 
            +
                            </ul>
         | 
| 136 | 
            +
                          </div>
         | 
| 137 | 
            +
                        </div>
         | 
| 138 | 
            +
                      </div>
         | 
| 139 | 
            +
                    <% end %>
         | 
| 140 | 
            +
                    <%= tag.div id: dom_id(job, "params"), class: "job-params list-group-item collapse small bg-dark text-light" do %>
         | 
| 141 | 
            +
                      <%= tag.pre JSON.pretty_generate(job.display_serialized_params) %>
         | 
| 142 | 
            +
                    <% end %>
         | 
| 143 | 
            +
                  <% end %>
         | 
| 144 | 
            +
                <% else %>
         | 
| 145 | 
            +
                  <div class="list-group-item py-4 text-center text-muted">
         | 
| 146 | 
            +
                    No jobs found.
         | 
| 147 | 
            +
                  </div>
         | 
| 120 148 | 
             
                <% end %>
         | 
| 121 149 | 
             
              </div>
         | 
| 122 150 | 
             
            </div>
         | 
| 151 | 
            +
            <% end %>
         | 
| @@ -1,48 +1,57 @@ | |
| 1 1 | 
             
            <div class="break-out bg-light border-bottom py-2 mb-3">
         | 
| 2 2 | 
             
              <div class="container-fluid pt-2">
         | 
| 3 | 
            -
                <div class=" | 
| 4 | 
            -
                  <div class=" | 
| 3 | 
            +
                <div class="row align-items-center">
         | 
| 4 | 
            +
                  <div class="col-5">
         | 
| 5 5 | 
             
                    <nav aria-label="breadcrumb">
         | 
| 6 6 | 
             
                      <ol class="breadcrumb small mb-0">
         | 
| 7 7 | 
             
                        <li class="breadcrumb-item"><%= link_to "Jobs", jobs_path %></li>
         | 
| 8 | 
            -
                        <li class="breadcrumb-item active" aria-current="page" | 
| 8 | 
            +
                        <li class="breadcrumb-item active" aria-current="page"><%= tag.code @job.id, class: "text-muted" %></li>
         | 
| 9 9 | 
             
                      </ol>
         | 
| 10 10 | 
             
                    </nav>
         | 
| 11 | 
            -
                    <h2 class="mb- | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 11 | 
            +
                    <h2 class="mb-0"><%= tag.code @job.job_class %></h2>
         | 
| 12 | 
            +
                  </div>
         | 
| 13 | 
            +
                  <div class="col-2">
         | 
| 14 | 
            +
                    <div class="small text-muted text-uppercase">Queue</div>
         | 
| 15 | 
            +
                    <div class="badge bg-primary bg-opacity-25 text-dark font-monospace my-2">
         | 
| 16 | 
            +
                      <%= tag.strong @job.queue_name %>
         | 
| 16 17 | 
             
                    </div>
         | 
| 17 18 | 
             
                  </div>
         | 
| 18 | 
            -
                  <div>
         | 
| 19 | 
            -
                     | 
| 20 | 
            -
                     | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 19 | 
            +
                  <div class="col-2">
         | 
| 20 | 
            +
                    <div class="small text-muted text-uppercase">Priority</div>
         | 
| 21 | 
            +
                    <div class="font-monospace fw-bold small my-2"><%= tag.strong @job.priority %></div>
         | 
| 22 | 
            +
                  </div>
         | 
| 23 | 
            +
                  <div class="col text-end">
         | 
| 24 | 
            +
                    <% if @job.status.in? [:scheduled, :retried, :queued] %>
         | 
| 25 | 
            +
                      <%= button_to reschedule_job_path(@job.id), method: :put,
         | 
| 26 | 
            +
                          class: "btn btn-sm btn-outline-primary",
         | 
| 27 | 
            +
                          form_class: "d-inline-block",
         | 
| 28 | 
            +
                          aria: { label: "Reschedule job" },
         | 
| 29 | 
            +
                          title: "Reschedule job",
         | 
| 30 | 
            +
                          data: { confirm: "Confirm reschedule" } do %>
         | 
| 31 | 
            +
                        <%= render_icon "skip_forward" %>
         | 
| 32 | 
            +
                        Reschedule
         | 
| 33 | 
            +
                      <% end %>
         | 
| 29 34 | 
             
                    <% end %>
         | 
| 30 35 |  | 
| 31 | 
            -
                    <%  | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 36 | 
            +
                    <% if @job.status.in? [:scheduled, :retried, :queued] %>
         | 
| 37 | 
            +
                      <%= button_to discard_job_path(@job.id), method: :put, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Discard job" }, title: "Discard job", data: { confirm: "Confirm discard" } do %>
         | 
| 38 | 
            +
                        <%= render_icon "stop" %>
         | 
| 39 | 
            +
                        Discard
         | 
| 40 | 
            +
                      <% end %>
         | 
| 35 41 | 
             
                    <% end %>
         | 
| 36 42 |  | 
| 37 | 
            -
                     | 
| 38 | 
            -
                      <%=  | 
| 39 | 
            -
             | 
| 43 | 
            +
                    <% if @job.status == :discarded %>
         | 
| 44 | 
            +
                      <%= button_to retry_job_path(@job.id), method: :put, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Retry job" }, title: "Retry job", data: { confirm: "Confirm retry" } do %>
         | 
| 45 | 
            +
                        <%= render_icon "arrow_clockwise" %>
         | 
| 46 | 
            +
                        Retry
         | 
| 47 | 
            +
                      <% end %>
         | 
| 40 48 | 
             
                    <% end %>
         | 
| 41 49 |  | 
| 42 | 
            -
                    <%  | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 50 | 
            +
                    <% if @job.status.in? [:discarded, :finished] %>
         | 
| 51 | 
            +
                      <%= button_to job_path(@job.id), method: :delete, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Destroy job" }, title: "Destroy job", data: { confirm: "Confirm destroy" } do %>
         | 
| 52 | 
            +
                        <%= render_icon "trash" %>
         | 
| 53 | 
            +
                        Destroy
         | 
| 54 | 
            +
                      <% end %>
         | 
| 46 55 | 
             
                    <% end %>
         | 
| 47 56 | 
             
                  </div>
         | 
| 48 57 | 
             
                </div>
         | 
| @@ -51,7 +60,7 @@ | |
| 51 60 |  | 
| 52 61 | 
             
            <div class="my-4">
         | 
| 53 62 | 
             
              <h5>Arguments</h5>
         | 
| 54 | 
            -
              <%= tag.pre @job.serialized_params["arguments"].map(&:inspect).join(', ') %>
         | 
| 63 | 
            +
              <%= tag.pre @job.serialized_params["arguments"].map(&:inspect).join(', '), class: 'text-wrap text-break' %>
         | 
| 55 64 | 
             
            </div>
         | 
| 56 65 |  | 
| 57 | 
            -
            <%= render 'executions', executions: @job.executions.reverse %>
         | 
| 66 | 
            +
            <%= render 'executions', executions: @job.executions.includes_advisory_locks.reverse %>
         | 
| @@ -1,38 +1,66 @@ | |
| 1 | 
            -
            <div class=" | 
| 2 | 
            -
              <h2>Processes</h2>
         | 
| 1 | 
            +
            <div class="bg-light break-out border-bottom">
         | 
| 2 | 
            +
              <h2 class="container-fluid pt-3 pb-2">Processes</h2>
         | 
| 3 3 | 
             
            </div>
         | 
| 4 4 |  | 
| 5 | 
            -
            <div data-live-poll-region="processes">
         | 
| 6 | 
            -
               | 
| 7 | 
            -
                < | 
| 8 | 
            -
                  <div class=" | 
| 9 | 
            -
                    < | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
                       | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
                          <td><%= process.id %></td>
         | 
| 21 | 
            -
                          <td><%= relative_time(process.created_at) %></td>
         | 
| 22 | 
            -
                          <td><%= tag.pre JSON.pretty_generate(process.state) %></td>
         | 
| 23 | 
            -
                        </tr>
         | 
| 5 | 
            +
            <div class="card my-3" data-live-poll-region="processes">
         | 
| 6 | 
            +
              <div class="list-group list-group-flush text-nowrap" role="table">
         | 
| 7 | 
            +
                <header class="list-group-item bg-light">
         | 
| 8 | 
            +
                  <div class="row small text-muted text-uppercase align-items-center">
         | 
| 9 | 
            +
                    <div class="col">Process</div>
         | 
| 10 | 
            +
                    <div class="col">Schedulers</div>
         | 
| 11 | 
            +
                    <div class="col-2 d-flex gap-2">
         | 
| 12 | 
            +
                      <span>Started</span>
         | 
| 13 | 
            +
                    </div>
         | 
| 14 | 
            +
                    <div class="col-auto">
         | 
| 15 | 
            +
                      <%= tag.button type: "button", class: "btn btn-sm text-muted ms-auto", role: "button",
         | 
| 16 | 
            +
                                     data: { bs_toggle: "collapse", bs_target: ".process-state" },
         | 
| 17 | 
            +
                                     aria: { expanded: false, controls: @processes.map { |process| "##{dom_id(process, 'state')}" }.join(" ") } do %>
         | 
| 18 | 
            +
                          <%= render_icon "info" %>
         | 
| 19 | 
            +
                          <span class="visually-hidden">Inspect</span>
         | 
| 24 20 | 
             
                      <% end %>
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                    </table>
         | 
| 21 | 
            +
                    </div>
         | 
| 27 22 | 
             
                  </div>
         | 
| 28 | 
            -
                </ | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 23 | 
            +
                </header>
         | 
| 24 | 
            +
                <% @processes.each do |process| %>
         | 
| 25 | 
            +
                  <div id="<%= dom_id(process) %>" class="<%= dom_class(process) %> list-group-item py-3" role="row">
         | 
| 26 | 
            +
                    <div class="row align-items-center">
         | 
| 27 | 
            +
                      <div class="col">
         | 
| 28 | 
            +
                        <code class="font-monospace">
         | 
| 29 | 
            +
                          <span class="text-muted opacity-50">$</span>
         | 
| 30 | 
            +
                          <%= process.state["proctitle"] %>
         | 
| 31 | 
            +
                        </code>
         | 
| 32 | 
            +
                        <div>
         | 
| 33 | 
            +
                          <span class="text-muted small">PID</span>
         | 
| 34 | 
            +
                          <span class="badge rounded-pill bg-light text-dark"><%= process.state["pid"] %></span>
         | 
| 35 | 
            +
                          <span class="text-muted small">@</span>
         | 
| 36 | 
            +
                          <span class="badge rounded-pill bg-light text-dark"><%= process.state["hostname"] %></span>
         | 
| 37 | 
            +
                        </div>
         | 
| 38 | 
            +
                      </div>
         | 
| 39 | 
            +
                      <div class="col">
         | 
| 40 | 
            +
                        <% process.state["schedulers"].each do |scheduler| %>
         | 
| 41 | 
            +
                          <pre class="mb-0"><%= scheduler %></pre>
         | 
| 42 | 
            +
                        <% end %>
         | 
| 43 | 
            +
                      </div>
         | 
| 44 | 
            +
                      <div class="col-2 small"><%= relative_time(process.created_at) %></div>
         | 
| 45 | 
            +
                      <div class="col-auto">
         | 
| 46 | 
            +
                        <%= tag.button type: "button", class: "btn btn-sm text-muted ms-auto", role: "button",
         | 
| 47 | 
            +
                                       title: "Inspect",
         | 
| 48 | 
            +
                                       data: { bs_toggle: "collapse", bs_target: "##{dom_id(process, 'state')}" },
         | 
| 49 | 
            +
                                       aria: { expanded: false, controls: dom_id(process, "state") } do %>
         | 
| 50 | 
            +
                          <%= render_icon "info" %>
         | 
| 51 | 
            +
                          <span class="visually-hidden">Inspect</span>
         | 
| 52 | 
            +
                        <% end %>
         | 
| 53 | 
            +
                      </div>
         | 
| 54 | 
            +
                    </div>
         | 
| 35 55 | 
             
                  </div>
         | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 56 | 
            +
                  <%= tag.div id: dom_id(process, "state"), class: "process-state list-group-item collapse small bg-dark text-light" do %>
         | 
| 57 | 
            +
                    <%= tag.pre JSON.pretty_generate(process.state) %>
         | 
| 58 | 
            +
                  <% end %>
         | 
| 59 | 
            +
                <% end %>
         | 
| 60 | 
            +
                <% if @processes.empty? %>
         | 
| 61 | 
            +
                  <div class="list-group-item py-4 text-center text-muted">
         | 
| 62 | 
            +
                    No GoodJob processes found.
         | 
| 63 | 
            +
                  </div>
         | 
| 64 | 
            +
                <% end %>
         | 
| 65 | 
            +
              </div>
         | 
| 38 66 | 
             
            </div>
         | 
| @@ -11,7 +11,7 @@ | |
| 11 11 | 
             
                    <li class="nav-item">
         | 
| 12 12 | 
             
                      <%= link_to url_for({state: name}), class: "nav-link #{"active" if params[:state] == name}" do %>
         | 
| 13 13 | 
             
                        <%= t(name, scope: 'good_job.status') %>
         | 
| 14 | 
            -
                        <span class="badge bg-primary rounded-pill <%= "bg-secondary" if count == 0 %>"><%= count %></span>
         | 
| 14 | 
            +
                        <span class="badge bg-primary rounded-pill <%= "bg-secondary" if count == 0 %>"><%= number_with_delimiter(count) %></span>
         | 
| 15 15 | 
             
                      <% end %>
         | 
| 16 16 | 
             
                    </li>
         | 
| 17 17 | 
             
                  <% end %>
         | 
| @@ -8,13 +8,25 @@ | |
| 8 8 | 
             
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
         | 
| 9 9 | 
             
                  <ul class="navbar-nav me-auto">
         | 
| 10 10 | 
             
                    <li class="nav-item">
         | 
| 11 | 
            -
                      <%= link_to  | 
| 11 | 
            +
                      <%= link_to jobs_path, class: ["nav-link", ("active" if controller_name == 'jobs')] do %>
         | 
| 12 | 
            +
                        <%= t(".jobs") %>
         | 
| 13 | 
            +
                        <% jobs_count = GoodJob::Job.count %>
         | 
| 14 | 
            +
                        <span class="badge bg-secondary rounded-pill"><%= number_to_human(jobs_count) %></span>
         | 
| 15 | 
            +
                    <% end %>
         | 
| 12 16 | 
             
                    </li>
         | 
| 13 17 | 
             
                    <li class="nav-item">
         | 
| 14 | 
            -
                      <%= link_to  | 
| 18 | 
            +
                      <%= link_to cron_entries_path, class: ["nav-link", ("active" if controller_name == 'cron_entries')] do %>
         | 
| 19 | 
            +
                        <%= t(".cron_schedules") %>
         | 
| 20 | 
            +
                        <% cron_entries_count = GoodJob::CronEntry.all.size %>
         | 
| 21 | 
            +
                        <span class="badge bg-secondary rounded-pill"><%= cron_entries_count %></span>
         | 
| 22 | 
            +
                    <% end %>
         | 
| 15 23 | 
             
                    </li>
         | 
| 16 24 | 
             
                    <li class="nav-item">
         | 
| 17 | 
            -
                      <%= link_to  | 
| 25 | 
            +
                      <%= link_to processes_path, class: ["nav-link", ("active" if controller_name == 'processes')] do %>
         | 
| 26 | 
            +
                        <%= t(".processes") %>
         | 
| 27 | 
            +
                        <% processes_count = GoodJob::Process.count %>
         | 
| 28 | 
            +
                        <span class="badge bg-secondary rounded-pill <%= "bg-danger" if processes_count == 0 %>"><%= processes_count %></span>
         | 
| 29 | 
            +
                      <% end %>
         | 
| 18 30 | 
             
                    </li>
         | 
| 19 31 | 
             
                  </ul>
         | 
| 20 32 | 
             
                  <div class="nav-item pe-2">
         | 
| @@ -0,0 +1,3 @@ | |
| 1 | 
            +
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
         | 
| 2 | 
            +
              <path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" />
         | 
| 3 | 
            +
            </svg>
         | 
| @@ -0,0 +1,4 @@ | |
| 1 | 
            +
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
         | 
| 2 | 
            +
              <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
         | 
| 3 | 
            +
              <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
         | 
| 4 | 
            +
            </svg>
         | 
    
        data/config/locales/en.yml
    CHANGED
    
    | @@ -63,3 +63,22 @@ en: | |
| 63 63 | 
             
                  retried: Retried
         | 
| 64 64 | 
             
                  running: Running
         | 
| 65 65 | 
             
                  scheduled: Scheduled
         | 
| 66 | 
            +
              number:
         | 
| 67 | 
            +
                format:
         | 
| 68 | 
            +
                  delimiter: ","
         | 
| 69 | 
            +
                  separator: "."
         | 
| 70 | 
            +
                human:
         | 
| 71 | 
            +
                  decimal_units:
         | 
| 72 | 
            +
                    format: "%n%u"
         | 
| 73 | 
            +
                    units:
         | 
| 74 | 
            +
                      billion: B
         | 
| 75 | 
            +
                      hundred: ''
         | 
| 76 | 
            +
                      million: M
         | 
| 77 | 
            +
                      quadrillion: Q
         | 
| 78 | 
            +
                      thousand: K
         | 
| 79 | 
            +
                      trillion: T
         | 
| 80 | 
            +
                      unit: ''
         | 
| 81 | 
            +
                  format:
         | 
| 82 | 
            +
                    delimiter: ","
         | 
| 83 | 
            +
                    precision: 3
         | 
| 84 | 
            +
                    separator: "."
         | 
    
        data/config/locales/es.yml
    CHANGED
    
    | @@ -63,3 +63,22 @@ es: | |
| 63 63 | 
             
                  retried: reintentado
         | 
| 64 64 | 
             
                  running: Corriendo
         | 
| 65 65 | 
             
                  scheduled: Programado
         | 
| 66 | 
            +
              number:
         | 
| 67 | 
            +
                format:
         | 
| 68 | 
            +
                  delimiter: " "
         | 
| 69 | 
            +
                  separator: ","
         | 
| 70 | 
            +
                human:
         | 
| 71 | 
            +
                  decimal_units:
         | 
| 72 | 
            +
                    format: "%n%u"
         | 
| 73 | 
            +
                    units:
         | 
| 74 | 
            +
                      billion: B
         | 
| 75 | 
            +
                      hundred: ''
         | 
| 76 | 
            +
                      million: M
         | 
| 77 | 
            +
                      quadrillion: q
         | 
| 78 | 
            +
                      thousand: k
         | 
| 79 | 
            +
                      trillion: T
         | 
| 80 | 
            +
                      unit: ''
         | 
| 81 | 
            +
                  format:
         | 
| 82 | 
            +
                    delimiter: " "
         | 
| 83 | 
            +
                    precision: 3
         | 
| 84 | 
            +
                    separator: ","
         | 
    
        data/config/locales/nl.yml
    CHANGED
    
    | @@ -63,3 +63,22 @@ nl: | |
| 63 63 | 
             
                  retried: Opnieuw geprobeerd
         | 
| 64 64 | 
             
                  running: Rennen
         | 
| 65 65 | 
             
                  scheduled: Gepland
         | 
| 66 | 
            +
              number:
         | 
| 67 | 
            +
                format:
         | 
| 68 | 
            +
                  delimiter: "."
         | 
| 69 | 
            +
                  separator: ","
         | 
| 70 | 
            +
                human:
         | 
| 71 | 
            +
                  decimal_units:
         | 
| 72 | 
            +
                    format: "%n%u"
         | 
| 73 | 
            +
                    units:
         | 
| 74 | 
            +
                      billion: B
         | 
| 75 | 
            +
                      hundred: ''
         | 
| 76 | 
            +
                      million: M
         | 
| 77 | 
            +
                      quadrillion: Q
         | 
| 78 | 
            +
                      thousand: K
         | 
| 79 | 
            +
                      trillion: T
         | 
| 80 | 
            +
                      unit: ''
         | 
| 81 | 
            +
                  format:
         | 
| 82 | 
            +
                    delimiter: "."
         | 
| 83 | 
            +
                    precision: 3
         | 
| 84 | 
            +
                    separator: ","
         | 
    
        data/config/locales/ru.yml
    CHANGED
    
    | @@ -87,3 +87,22 @@ ru: | |
| 87 87 | 
             
                  retried: Повторная попытка
         | 
| 88 88 | 
             
                  running: Бег
         | 
| 89 89 | 
             
                  scheduled: по расписанию
         | 
| 90 | 
            +
              number:
         | 
| 91 | 
            +
                format:
         | 
| 92 | 
            +
                  delimiter: " "
         | 
| 93 | 
            +
                  separator: ","
         | 
| 94 | 
            +
                human:
         | 
| 95 | 
            +
                  decimal_units:
         | 
| 96 | 
            +
                    format: "%n%u"
         | 
| 97 | 
            +
                    units:
         | 
| 98 | 
            +
                      billion: Б
         | 
| 99 | 
            +
                      hundred: ''
         | 
| 100 | 
            +
                      million: М
         | 
| 101 | 
            +
                      quadrillion: Q
         | 
| 102 | 
            +
                      thousand: К
         | 
| 103 | 
            +
                      trillion: Т
         | 
| 104 | 
            +
                      unit: ''
         | 
| 105 | 
            +
                  format:
         | 
| 106 | 
            +
                    delimiter: " "
         | 
| 107 | 
            +
                    precision: 3
         | 
| 108 | 
            +
                    separator: ","
         |