mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-10 17:36:33 +08:00
Merge pull request #2839 from okriuchykhin/ok_SCI_4978
Move some consequence executon into background process [SCI-4978]
This commit is contained in:
commit
51d69f9442
17 changed files with 139 additions and 38 deletions
|
@ -1,6 +1,8 @@
|
|||
/* global I18n dropdownSelector HelperModule animateSpinner */
|
||||
/* eslint-disable no-use-before-define */
|
||||
|
||||
const STATUS_POLLING_INTERVAL = 5000;
|
||||
|
||||
function initTaskCollapseState() {
|
||||
let taskView = '.my-modules-protocols-index';
|
||||
let taskSection = '.task-section-caret';
|
||||
|
@ -236,7 +238,20 @@ function bindEditTagsAjax() {
|
|||
});
|
||||
}
|
||||
|
||||
function checkStatusState() {
|
||||
$.getJSON($('.status-flow-dropdown').data('status-check-url'), (statusData) => {
|
||||
if (statusData.status_changing) {
|
||||
setTimeout(() => { checkStatusState(); }, STATUS_POLLING_INTERVAL);
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function applyTaskStatusChangeCallBack() {
|
||||
if ($('.status-flow-dropdown').data('status-changing')) {
|
||||
setTimeout(() => { checkStatusState(); }, STATUS_POLLING_INTERVAL);
|
||||
}
|
||||
$('.task-flows').on('click', '#dropdownTaskFlowList > li[data-state-id]', function() {
|
||||
var list = $('#dropdownTaskFlowList');
|
||||
var item = $(this);
|
||||
|
|
|
@ -31,7 +31,8 @@ class MyModuleRepositorySnapshotsController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
repository_snapshot = @repository.provision_snapshot(@my_module, current_user)
|
||||
repository_snapshot = RepositorySnapshot.create_preliminary(@repository, @my_module, current_user)
|
||||
RepositorySnapshotProvisioningJob.perform_later(repository_snapshot)
|
||||
|
||||
render json: {
|
||||
html: render_to_string(partial: 'my_modules/repositories/full_view_version',
|
||||
|
|
|
@ -11,8 +11,7 @@ class MyModulesController < ApplicationController
|
|||
before_action :load_projects_tree, only: %i(protocols results activities archive)
|
||||
before_action :check_archive_and_restore_permissions, only: %i(update)
|
||||
before_action :check_manage_permissions, only: %i(description due_date update_description update_protocol_description)
|
||||
before_action :check_view_permissions, except: %i(update update_description update_protocol_description
|
||||
toggle_task_state)
|
||||
before_action :check_view_permissions, except: %i(update update_description update_protocol_description)
|
||||
before_action :check_update_state_permissions, only: :update_state
|
||||
before_action :set_inline_name_editing, only: %i(protocols results activities archive)
|
||||
|
||||
|
@ -46,6 +45,14 @@ class MyModulesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def status_state
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: { status_changing: @my_module.status_changing? }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def activities
|
||||
params[:subjects] = {
|
||||
MyModule: [@my_module.id]
|
||||
|
|
24
app/jobs/my_module_status_consequences_job.rb
Normal file
24
app/jobs/my_module_status_consequences_job.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MyModuleStatusConsequencesJob < ApplicationJob
|
||||
queue_as :high_priority
|
||||
|
||||
def perform(my_module, my_module_status_consequences)
|
||||
error_raised = false
|
||||
my_module.transaction do
|
||||
my_module_status_consequences.each do |consequence|
|
||||
consequence.call(my_module)
|
||||
end
|
||||
my_module.update!(status_changing: false)
|
||||
rescue StandardError => e
|
||||
Rails.logger.error(e.message)
|
||||
Rails.logger.error(e.backtrace.join("\n"))
|
||||
error_raised = true
|
||||
end
|
||||
if error_raised
|
||||
my_module.my_module_status = my_module.changing_from_my_module_status
|
||||
my_module.status_changing = false
|
||||
my_module.save!
|
||||
end
|
||||
end
|
||||
end
|
|
@ -27,11 +27,7 @@ class MyModule < ApplicationRecord
|
|||
validate :check_status, if: :my_module_status_id_changed?
|
||||
validate :check_status_conditions, if: :my_module_status_id_changed?
|
||||
validate :check_status_implications, unless: proc { |mm|
|
||||
mm.my_module_status_id_changed? ||
|
||||
mm.x_changed? ||
|
||||
mm.y_changed? ||
|
||||
mm.my_module_group_id_changed? ||
|
||||
mm.workflow_order_changed?
|
||||
(mm.changed_attributes.keys - %w(my_module_status_id x y my_module_group_id workflow_order status_changing)).blank?
|
||||
}
|
||||
|
||||
belongs_to :created_by,
|
||||
|
@ -53,6 +49,7 @@ class MyModule < ApplicationRecord
|
|||
belongs_to :experiment, inverse_of: :my_modules, touch: true
|
||||
belongs_to :my_module_group, inverse_of: :my_modules, optional: true
|
||||
belongs_to :my_module_status, optional: true
|
||||
belongs_to :changing_from_my_module_status, optional: true, class_name: 'MyModuleStatus'
|
||||
delegate :my_module_status_flow, to: :my_module_status, allow_nil: true
|
||||
has_many :results, inverse_of: :my_module, dependent: :destroy
|
||||
has_many :my_module_tags, inverse_of: :my_module, dependent: :destroy
|
||||
|
@ -568,10 +565,17 @@ class MyModule < ApplicationRecord
|
|||
end
|
||||
|
||||
def exec_status_consequences
|
||||
return if my_module_status.blank?
|
||||
return if my_module_status.blank? || status_changing
|
||||
|
||||
my_module_status.my_module_status_consequences.each do |consequence|
|
||||
consequence.call(self)
|
||||
self.changing_from_my_module_status_id = my_module_status_id_was if my_module_status_id_was.present?
|
||||
|
||||
if my_module_status.my_module_status_consequences.any?(&:runs_in_background?)
|
||||
self.status_changing = true
|
||||
MyModuleStatusConsequencesJob.perform_later(self, my_module_status.my_module_status_consequences.to_a)
|
||||
else
|
||||
my_module_status.my_module_status_consequences.each do |consequence|
|
||||
consequence.call(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,4 +2,8 @@
|
|||
|
||||
class MyModuleStatusConsequence < ApplicationRecord
|
||||
belongs_to :my_module_status
|
||||
|
||||
def runs_in_background?
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,9 +2,18 @@
|
|||
|
||||
module MyModuleStatusConsequences
|
||||
class RepositorySnapshot < MyModuleStatusConsequence
|
||||
def runs_in_background?
|
||||
true
|
||||
end
|
||||
|
||||
def call(my_module)
|
||||
my_module.assigned_repositories.each do |repository|
|
||||
repository.provision_snapshot(my_module)
|
||||
repository_snapshot = ::RepositorySnapshot.create_preliminary(repository, my_module)
|
||||
service = Repositories::SnapshotProvisioningService.call(repository_snapshot: repository_snapshot)
|
||||
unless service.succeed?
|
||||
repository_snapshot.failed!
|
||||
raise StandardError, service.errors
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -209,21 +209,6 @@ class Repository < RepositoryBase
|
|||
importer.run
|
||||
end
|
||||
|
||||
def provision_snapshot(my_module, created_by = nil)
|
||||
created_by ||= self.created_by
|
||||
repository_snapshot = dup.becomes(RepositorySnapshot)
|
||||
repository_snapshot.assign_attributes(type: RepositorySnapshot.name,
|
||||
original_repository: self,
|
||||
my_module: my_module,
|
||||
created_by: created_by,
|
||||
team: my_module.experiment.project.team,
|
||||
permission_level: Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:not_shared])
|
||||
repository_snapshot.provisioning!
|
||||
repository_snapshot.reload
|
||||
RepositorySnapshotProvisioningJob.perform_later(repository_snapshot)
|
||||
repository_snapshot
|
||||
end
|
||||
|
||||
def assigned_rows(my_module)
|
||||
repository_rows.joins(:my_module_repository_rows).where(my_module_repository_rows: { my_module_id: my_module.id })
|
||||
end
|
||||
|
|
|
@ -26,6 +26,19 @@ class RepositorySnapshot < RepositoryBase
|
|||
.order(:parent_id, updated_at: :desc)
|
||||
}
|
||||
|
||||
def self.create_preliminary(repository, my_module, created_by = nil)
|
||||
created_by ||= repository.created_by
|
||||
repository_snapshot = repository.dup.becomes(RepositorySnapshot)
|
||||
repository_snapshot.assign_attributes(type: RepositorySnapshot.name,
|
||||
original_repository: repository,
|
||||
my_module: my_module,
|
||||
created_by: created_by,
|
||||
team: my_module.experiment.project.team,
|
||||
permission_level: Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:not_shared])
|
||||
repository_snapshot.provisioning!
|
||||
repository_snapshot.reload
|
||||
end
|
||||
|
||||
def default_columns_count
|
||||
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['length']
|
||||
end
|
||||
|
|
|
@ -11,6 +11,7 @@ Canaid::Permissions.register_for(MyModule) do
|
|||
.each do |perm|
|
||||
can perm do |_, my_module|
|
||||
my_module.active? &&
|
||||
!my_module.status_changing? &&
|
||||
my_module.experiment.active? &&
|
||||
my_module.experiment.project.active?
|
||||
end
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
<% end %>
|
||||
</div>
|
||||
<div class="status-label" style="--state-color: <%= my_module.my_module_status.color %>">
|
||||
<% if my_module.status_changing %>
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
<span><%= t('experiments.canvas.full_zoom.status_transitioning_label') %></span>
|
||||
<% end %>
|
||||
<%= my_module.my_module_status.name %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
<% status = my_module.my_module_status %>
|
||||
<div class="status-label"><%= t('my_module_statuses.dropdown.status_label') %></div>
|
||||
<div class="dropdown sci-dropdown status-flow-dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle"
|
||||
<div class="status-label">
|
||||
<%= t('my_module_statuses.dropdown.status_label') %>
|
||||
</div>
|
||||
<div class="dropdown sci-dropdown status-flow-dropdown"
|
||||
data-status-changing="<%= my_module.status_changing %>"
|
||||
data-status-check-url="<%= status_state_my_module_path(my_module) %>">
|
||||
<button class="btn btn-secondary dropdown-toggle <%= 'disabled' if my_module.status_changing %>"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="true"
|
||||
style="<%= "background-color: #{status.color}" %>;">
|
||||
<span><%= status.name %></span>
|
||||
<span>
|
||||
<% if my_module.status_changing %>
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
<span><%= t('my_module_statuses.dropdown.status_transitioning_label') %></span>
|
||||
<% end %>
|
||||
<%= status.name %>
|
||||
</span>
|
||||
<span class="caret pull-right"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownTaskFlow" id="dropdownTaskFlowList" data-link-url="<%= update_state_my_module_url(my_module) %>">
|
||||
|
|
|
@ -989,6 +989,7 @@ en:
|
|||
full_zoom:
|
||||
due_date: "Due date"
|
||||
no_due_date: "not set"
|
||||
status_transitioning_label: "Transitioning to:"
|
||||
modal_manage_users:
|
||||
modal_title: "Manage users for"
|
||||
no_users: "No users"
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
en:
|
||||
my_module_statuses:
|
||||
dropdown:
|
||||
status_label: Status
|
||||
move_label: Move to
|
||||
return_label: Return to
|
||||
view_flow_label: View task flow
|
||||
status_label: 'Status'
|
||||
status_transitioning_label: 'Transitioning to:'
|
||||
move_label: 'Move to'
|
||||
return_label: 'Return to'
|
||||
view_flow_label: 'View task flow'
|
||||
update_status:
|
||||
error:
|
||||
no_permission: You dont have permission to change the status
|
||||
no_permission: 'You dont have permission to change the status'
|
||||
conditions:
|
||||
error:
|
||||
my_module_not_active: 'Task should be active'
|
||||
|
|
|
@ -392,6 +392,7 @@ Rails.application.routes.draw do
|
|||
post 'activities'
|
||||
get 'activities_tab' # Activities in tab view for single module
|
||||
get 'due_date'
|
||||
get 'status_state'
|
||||
patch 'description',
|
||||
to: 'my_modules#update_description',
|
||||
as: 'update_description'
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddStatusChangingFlagToMyModule < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
change_table :my_modules do |t|
|
||||
t.boolean :status_changing, default: false
|
||||
t.references :changing_from_my_module_status, foreign_key: { to_table: :my_module_statuses }, index: false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -851,7 +851,9 @@ CREATE TABLE public.my_modules (
|
|||
state smallint DEFAULT 0,
|
||||
completed_on timestamp without time zone,
|
||||
started_on timestamp without time zone,
|
||||
my_module_status_id bigint
|
||||
my_module_status_id bigint,
|
||||
status_changing boolean DEFAULT false,
|
||||
changing_from_my_module_status_id bigint
|
||||
);
|
||||
|
||||
|
||||
|
@ -6397,6 +6399,14 @@ ALTER TABLE ONLY public.repository_number_values
|
|||
ADD CONSTRAINT fk_rails_3df53c9b27 FOREIGN KEY (created_by_id) REFERENCES public.users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: my_modules fk_rails_4768515e2e; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.my_modules
|
||||
ADD CONSTRAINT fk_rails_4768515e2e FOREIGN KEY (changing_from_my_module_status_id) REFERENCES public.my_module_statuses(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: projects fk_rails_47aee20018; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -7626,6 +7636,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('20200709142830'),
|
||||
('20200713142353'),
|
||||
('20200714082503'),
|
||||
('20200826143431');
|
||||
('20200826143431'),
|
||||
('20200909121441');
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue