diff --git a/app/controllers/gitolite_public_keys_controller.rb b/app/controllers/gitolite_public_keys_controller.rb index e11721d2b..131d2af40 100644 --- a/app/controllers/gitolite_public_keys_controller.rb +++ b/app/controllers/gitolite_public_keys_controller.rb @@ -10,21 +10,26 @@ def edit end def delete + GitHostingObserver.set_update_active(false) @gitolite_public_key[:active] = 0 @gitolite_public_key.save redirect_to url_for(:controller => 'my', :action => 'account') + GitHostingObserver.set_update_active(true) end def update + GitHostingObserver.set_update_active(false) if @gitolite_public_key.update_attributes(params[:public_key]) flash[:notice] = l(:notice_public_key_updated) redirect_to url_for(:controller => 'my', :action => 'account') else render :action => 'edit' end + GitHostingObserver.set_update_active(true) end def create + GitHostingObserver.set_update_active(false) @gitolite_public_key = GitolitePublicKey.new(params[:public_key].merge(:user => @user)) if @gitolite_public_key.save flash[:notice] = l(:notice_public_key_added) @@ -32,6 +37,7 @@ def create @gitolite_public_key = GitolitePublicKey.new(:user => @user) end redirect_to url_for(:controller => 'my', :action => 'account') + GitHostingObserver.set_update_active(true) end protected diff --git a/app/models/git_hosting_observer.rb b/app/models/git_hosting_observer.rb index 8b8de5462..f1db69976 100644 --- a/app/models/git_hosting_observer.rb +++ b/app/models/git_hosting_observer.rb @@ -2,6 +2,7 @@ class GitHostingObserver < ActiveRecord::Observer observe :project, :user, :gitolite_public_key, :member, :role, :repository @@updating_active = true + @@updating_active_stack = 0 @@cached_project_updates = [] def reload_this_observer @@ -12,14 +13,25 @@ def reload_this_observer def self.set_update_active(is_active) - @@updating_active = is_active - if is_active + if !is_active + @@updating_active_stack += 1 + else + @@updating_active_stack -= 1 + if @@updating_active_stack < 0 + @@updating_active_stack = 0 + end + end + + if is_active && @@updating_active_stack == 0 if @@cached_project_updates.length > 0 @@cached_project_updates = @@cached_project_updates.flatten.uniq.compact GitHosting::update_repositories(@@cached_project_updates, false) + @@cached_project_updates = [] end + @@updating_active = true + else + @@updating_active = false end - @@cached_project_updates = [] end diff --git a/db/migrate/20111119170948_add_indexes_to_gitolite_public_key.rb b/db/migrate/20111119170948_add_indexes_to_gitolite_public_key.rb new file mode 100644 index 000000000..d5596275e --- /dev/null +++ b/db/migrate/20111119170948_add_indexes_to_gitolite_public_key.rb @@ -0,0 +1,11 @@ +class AddIndexesToGitolitePublicKey < ActiveRecord::Migration + def self.up + add_index :gitolite_public_keys, :user_id + add_index :gitolite_public_keys, :identifier + end + + def self.down + remove_index :gitolite_public_keys, :user_id + remove_index :gitolite_public_keys, :identifier + end +end diff --git a/init.rb b/init.rb index 5567c40f2..721cdbaca 100755 --- a/init.rb +++ b/init.rb @@ -66,6 +66,22 @@ require 'git_hosting/patches/git_repository_patch' Repository::Git.send(:include, GitHosting::Patches::GitRepositoryPatch) + require_dependency 'sys_controller' + require 'git_hosting/patches/sys_controller_patch' + SysController.send(:include, GitHosting::Patches::SysControllerPatch) + + require_dependency 'members_controller' + require 'git_hosting/patches/members_controller_patch' + MembersController.send(:include, GitHosting::Patches::MembersControllerPatch) + + require_dependency 'users_controller' + require 'git_hosting/patches/users_controller_patch' + UsersController.send(:include, GitHosting::Patches::UsersControllerPatch) + + require_dependency 'roles_controller' + require 'git_hosting/patches/roles_controller_patch' + RolesController.send(:include, GitHosting::Patches::RolesControllerPatch) + require_dependency 'git_hosting/patches/repository_cia_filters' end diff --git a/lib/git_hosting/patches/git_repository_patch.rb b/lib/git_hosting/patches/git_repository_patch.rb index fb9cf2ead..af081f1ff 100644 --- a/lib/git_hosting/patches/git_repository_patch.rb +++ b/lib/git_hosting/patches/git_repository_patch.rb @@ -9,6 +9,16 @@ def extra_report_last_commit_with_always_true true end + def fetch_changesets_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + fetch_changesets_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end def self.included(base) base.class_eval do @@ -17,6 +27,7 @@ def self.included(base) begin base.send(:alias_method_chain, :report_last_commit, :always_true) base.send(:alias_method_chain, :extra_report_last_commit, :always_true) + base.send(:alias_method_chain, :fetch_changesets, :disable_update) rescue end diff --git a/lib/git_hosting/patches/members_controller_patch.rb b/lib/git_hosting/patches/members_controller_patch.rb new file mode 100644 index 000000000..af9d7d4cb --- /dev/null +++ b/lib/git_hosting/patches/members_controller_patch.rb @@ -0,0 +1,48 @@ +module GitHosting + module Patches + module MembersControllerPatch + def new_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + new_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + def edit_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + edit_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + def destroy_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + destroy_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + + def self.included(base) + base.class_eval do + unloadable + end + begin + base.send(:alias_method_chain, :new, :disable_update) + base.send(:alias_method_chain, :edit, :disable_update) + base.send(:alias_method_chain, :destroy, :disable_update) + rescue + end + end + end + end +end diff --git a/lib/git_hosting/patches/repository_patch.rb b/lib/git_hosting/patches/repository_patch.rb index 134915ca6..6c3695250 100644 --- a/lib/git_hosting/patches/repository_patch.rb +++ b/lib/git_hosting/patches/repository_patch.rb @@ -25,8 +25,17 @@ def factory_with_git_extra_init(klass_name, *args) end return new_repo end - end + def fetch_changesets_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + fetch_changesets_without_disable_update + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + end def self.included(base) base.extend(ClassMethods) @@ -34,9 +43,9 @@ def self.included(base) unloadable class << self alias_method_chain :factory, :git_extra_init + alias_method_chain :fetch_changesets, :disable_update end end - end end end diff --git a/lib/git_hosting/patches/roles_controller_patch.rb b/lib/git_hosting/patches/roles_controller_patch.rb new file mode 100644 index 000000000..33782df66 --- /dev/null +++ b/lib/git_hosting/patches/roles_controller_patch.rb @@ -0,0 +1,36 @@ +module GitHosting + module Patches + module RolesControllerPatch + def edit_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + edit_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + def destroy_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + destroy_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + def self.included(base) + base.class_eval do + unloadable + end + begin + base.send(:alias_method_chain, :edit, :disable_update) + base.send(:alias_method_chain, :destroy, :disable_update) + rescue + end + end + end + end +end diff --git a/lib/git_hosting/patches/sys_controller_patch.rb b/lib/git_hosting/patches/sys_controller_patch.rb new file mode 100644 index 000000000..6b35c86e5 --- /dev/null +++ b/lib/git_hosting/patches/sys_controller_patch.rb @@ -0,0 +1,26 @@ +module GitHosting + module Patches + module SysControllerPatch + def fetch_changesets_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + fetch_changesets_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + + def self.included(base) + base.class_eval do + unloadable + end + begin + base.send(:alias_method_chain, :fetch_changesets, :disable_update) + rescue + end + end + end + end +end diff --git a/lib/git_hosting/patches/users_controller_patch.rb b/lib/git_hosting/patches/users_controller_patch.rb new file mode 100644 index 000000000..e5f31f6c4 --- /dev/null +++ b/lib/git_hosting/patches/users_controller_patch.rb @@ -0,0 +1,59 @@ +module GitHosting + module Patches + module UsersControllerPatch + def create_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + create_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + def update_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + update_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + def destroy_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + destroy_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + def edit_membership_with_disable_update + # Turn of updates during repository update + GitHostingObserver.set_update_active(false); + + # Do actual update + edit_membership_without_disable_update + + # Reenable updates to perform a single update + GitHostingObserver.set_update_active(true); + end + + def self.included(base) + base.class_eval do + unloadable + end + begin + base.send(:alias_method_chain, :create, :disable_update) + base.send(:alias_method_chain, :update, :disable_update) + base.send(:alias_method_chain, :destroy, :disable_update) + base.send(:alias_method_chain, :edit_membershipt, :disable_update) + rescue + end + end + end + end +end