Commit 971662e6 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'stanhu/gitlab-ce-add-eager-load-lib' into 'master'

Add eager load paths to help prevent dependency load issues with Sidekiq workers

_Originally opened at !3545 by @stanhu._

- - -

Relevant resources:

- https://github.com/mperham/sidekiq/wiki/FAQ#why-doesnt-sidekiq-autoload-my-rails-application-code
- https://github.com/mperham/sidekiq/issues/1281#issuecomment-27129904
- http://blog.arkency.com/2014/11/dont-forget-about-eager-load-when-extending-autoload
- https://github.com/rails/rails/blob/52ce6ece8c8f74064bb64e0a0b1ddd83092718e1/railties/lib/rails/engine.rb#L472-L479
- https://github.com/rails/rails/blob/v4.2.6/railties/lib/rails/paths.rb

Attempts to address #3661, #11896, #12769, #13521, #14131, #14589, #14759, #14825.

See merge request !3724
parents 634f02b0 5589dcf8
...@@ -32,6 +32,7 @@ v 8.8.0 (unreleased) ...@@ -32,6 +32,7 @@ v 8.8.0 (unreleased)
- API: Expose Issue#user_notes_count. !3126 (Anton Popov) - API: Expose Issue#user_notes_count. !3126 (Anton Popov)
- Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718 - Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718
- Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes) - Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes)
- Add eager load paths to help prevent dependency load issues in Sidekiq workers. !3724
- Added multiple colors for labels in dropdowns when dups happen. - Added multiple colors for labels in dropdowns when dups happen.
- Improve description for the Two-factor Authentication sign-in screen. (Connor Shea) - Improve description for the Two-factor Authentication sign-in screen. (Connor Shea)
- API support for the 'since' and 'until' operators on commit requests (Paco Guzman) - API support for the 'since' and 'until' operators on commit requests (Paco Guzman)
......
...@@ -81,7 +81,7 @@ class Repository ...@@ -81,7 +81,7 @@ class Repository
def commit(id = 'HEAD') def commit(id = 'HEAD')
return nil unless exists? return nil unless exists?
commit = Gitlab::Git::Commit.find(raw_repository, id) commit = Gitlab::Git::Commit.find(raw_repository, id)
commit = Commit.new(commit, @project) if commit commit = ::Commit.new(commit, @project) if commit
commit commit
rescue Rugged::OdbError rescue Rugged::OdbError
nil nil
......
require File.expand_path('../boot', __FILE__) require File.expand_path('../boot', __FILE__)
require 'rails/all' require 'rails/all'
require 'devise'
I18n.config.enforce_available_locales = false
Bundler.require(:default, Rails.env) Bundler.require(:default, Rails.env)
require_relative '../lib/gitlab/redis'
module Gitlab module Gitlab
class Application < Rails::Application class Application < Rails::Application
require_dependency Rails.root.join('lib/gitlab/redis')
# Settings in config/environments/* take precedence over those specified here. # Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers # Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded. # -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable. # Sidekiq uses eager loading, but directories not in the standard Rails
config.autoload_paths.push(*%W(#{config.root}/lib # directories must be added to the eager load paths:
# https://github.com/mperham/sidekiq/wiki/FAQ#why-doesnt-sidekiq-autoload-my-rails-application-code
# Also, there is no need to add `lib` to autoload_paths since autoloading is
# configured to check for eager loaded paths:
# https://github.com/rails/rails/blob/v4.2.6/railties/lib/rails/engine.rb#L687
# This is a nice reference article on autoloading/eager loading:
# http://blog.arkency.com/2014/11/dont-forget-about-eager-load-when-extending-autoload
config.eager_load_paths.push(*%W(#{config.root}/lib
#{config.root}/app/models/ci
#{config.root}/app/models/hooks #{config.root}/app/models/hooks
#{config.root}/app/models/concerns #{config.root}/app/models/members
#{config.root}/app/models/project_services #{config.root}/app/models/project_services))
#{config.root}/app/models/members))
# Only load the plugins named here, in the order given (default is alphabetical). # Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named. # :all can be used as a placeholder for all plugins not explicitly named.
......
require 'gitlab' # Load lib/gitlab.rb as soon as possible require_dependency Rails.root.join('lib/gitlab') # Load Gitlab as soon as possible
class Settings < Settingslogic class Settings < Settingslogic
source ENV.fetch('GITLAB_CONFIG') { "#{Rails.root}/config/gitlab.yml" } source ENV.fetch('GITLAB_CONFIG') { "#{Rails.root}/config/gitlab.yml" }
......
# GIT over HTTP # GIT over HTTP
require Rails.root.join("lib", "gitlab", "backend", "grack_auth") require_dependency Rails.root.join('lib/gitlab/backend/grack_auth')
# GIT over SSH # GIT over SSH
require Rails.root.join("lib", "gitlab", "backend", "shell") require_dependency Rails.root.join('lib/gitlab/backend/shell')
# GitLab shell adapter # GitLab shell adapter
require Rails.root.join("lib", "gitlab", "backend", "shell_adapter") require_dependency Rails.root.join('lib/gitlab/backend/shell_adapter')
required_version = Gitlab::VersionInfo.parse(Gitlab::Shell.version_required) required_version = Gitlab::VersionInfo.parse(Gitlab::Shell.version_required)
current_version = Gitlab::VersionInfo.parse(Gitlab::Shell.new.version) current_version = Gitlab::VersionInfo.parse(Gitlab::Shell.new.version)
......
Dir["#{Rails.root}/lib/api/*.rb"].each {|file| require file}
module API module API
class API < Grape::API class API < Grape::API
include APIGuard include APIGuard
...@@ -25,38 +23,39 @@ module API ...@@ -25,38 +23,39 @@ module API
format :json format :json
content_type :txt, "text/plain" content_type :txt, "text/plain"
helpers Helpers # Ensure the namespace is right, otherwise we might load Grape::API::Helpers
helpers ::API::Helpers
mount Groups
mount GroupMembers mount ::API::Groups
mount Users mount ::API::GroupMembers
mount Projects mount ::API::Users
mount Repositories mount ::API::Projects
mount Issues mount ::API::Repositories
mount Milestones mount ::API::Issues
mount Session mount ::API::Milestones
mount MergeRequests mount ::API::Session
mount Notes mount ::API::MergeRequests
mount Internal mount ::API::Notes
mount SystemHooks mount ::API::Internal
mount ProjectSnippets mount ::API::SystemHooks
mount ProjectMembers mount ::API::ProjectSnippets
mount DeployKeys mount ::API::ProjectMembers
mount ProjectHooks mount ::API::DeployKeys
mount Services mount ::API::ProjectHooks
mount Files mount ::API::Services
mount Commits mount ::API::Files
mount CommitStatus mount ::API::Commits
mount Namespaces mount ::API::CommitStatuses
mount Branches mount ::API::Namespaces
mount Labels mount ::API::Branches
mount Settings mount ::API::Labels
mount Keys mount ::API::Settings
mount Tags mount ::API::Keys
mount Triggers mount ::API::Tags
mount Builds mount ::API::Triggers
mount Variables mount ::API::Builds
mount Runners mount ::API::Variables
mount Licenses mount ::API::Runners
mount ::API::Licenses
end end
end end
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
require 'rack/oauth2' require 'rack/oauth2'
module APIGuard module API
module APIGuard
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do |base| included do |base|
...@@ -80,6 +81,7 @@ module APIGuard ...@@ -80,6 +81,7 @@ module APIGuard
end end
private private
def find_access_token def find_access_token
@access_token ||= Doorkeeper.authenticate(doorkeeper_request, Doorkeeper.configuration.access_token_methods) @access_token ||= Doorkeeper.authenticate(doorkeeper_request, Doorkeeper.configuration.access_token_methods)
end end
...@@ -108,6 +110,7 @@ module APIGuard ...@@ -108,6 +110,7 @@ module APIGuard
end end
private private
def install_error_responders(base) def install_error_responders(base)
error_classes = [ MissingTokenError, TokenNotFoundError, error_classes = [ MissingTokenError, TokenNotFoundError,
ExpiredError, RevokedError, InsufficientScopeError] ExpiredError, RevokedError, InsufficientScopeError]
...@@ -169,4 +172,5 @@ module APIGuard ...@@ -169,4 +172,5 @@ module APIGuard
@scopes = scopes @scopes = scopes
end end
end end
end
end end
...@@ -2,7 +2,7 @@ require 'mime/types' ...@@ -2,7 +2,7 @@ require 'mime/types'
module API module API
# Project commit statuses API # Project commit statuses API
class CommitStatus < Grape::API class CommitStatuses < Grape::API
resource :projects do resource :projects do
before { authenticate! } before { authenticate! }
......
Dir["#{Rails.root}/lib/ci/api/*.rb"].each {|file| require file}
module Ci module Ci
module API module API
class API < Grape::API class API < Grape::API
include APIGuard include ::API::APIGuard
version 'v1', using: :path version 'v1', using: :path
rescue_from ActiveRecord::RecordNotFound do rescue_from ActiveRecord::RecordNotFound do
...@@ -31,9 +29,9 @@ module Ci ...@@ -31,9 +29,9 @@ module Ci
helpers ::API::Helpers helpers ::API::Helpers
helpers Gitlab::CurrentSettings helpers Gitlab::CurrentSettings
mount Builds mount ::Ci::API::Builds
mount Runners mount ::Ci::API::Runners
mount Triggers mount ::Ci::API::Triggers
end end
end end
end end
require 'gitlab/git' require_dependency 'gitlab/git'
module Gitlab module Gitlab
def self.com? def self.com?
......
require 'spec_helper' require 'spec_helper'
describe API::CommitStatus, api: true do describe API::CommitStatuses, api: true do
include ApiHelpers include ApiHelpers
let!(:project) { create(:project) } let!(:project) { create(:project) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment