Extend autofetching of commits into update repository information

This commit extends the previous functionality of *autofetch commits*
into internal updating of repository information, which encompasses:

* Commit information (changesets)
* Disk space information

They are now both retrieved when browsing the repository and the latter
is fetched asynchronously whenever the last update is older than the
timeout setting.

This timeout setting is now user-configurable.
This commit is contained in:
Oliver Günther
2015-08-17 17:29:57 +02:00
parent 2022a87532
commit 0b583c3ccf
10 changed files with 48 additions and 22 deletions
+4 -1
View File
@@ -115,7 +115,10 @@ class RepositoriesController < ApplicationController
end
def show
@repository.fetch_changesets if Setting.autofetch_changesets? && @path.blank?
if Setting.autofetch_changesets? && @path.blank?
@repository.fetch_changesets
@repository.update_required_storage
end
@entries = @repository.entries(@path, @rev)
@changeset = @repository.find_changeset_by_name(@rev)
+4 -3
View File
@@ -68,8 +68,8 @@ class SysController < ActionController::Base
end
def update_required_storage
update_storage_information(@repository, params[:force] == '1')
render nothing: true, status: 200
result = update_storage_information(@repository, params[:force] == '1')
render text: "Updated: #{result}", status: 200
end
def fetch_changesets
@@ -118,8 +118,9 @@ class SysController < ActionController::Base
def update_storage_information(repository, force = false)
if force
Delayed::Job.enqueue ::Scm::StorageUpdaterJob.new(repository)
true
else
repository.required_disk_storage
repository.update_required_storage
end
end
+3 -5
View File
@@ -52,14 +52,12 @@ module Project::Storage
}
end
# Workaround for PG adapter returning strings on aggregate functions
# TODO: This should be fixed and thus removed in Rails 4.
%w[required_disk_space work_package_required_space
wiki_required_space repositories_required_space].each do |attribute|
define_method attribute do
value = self.read_attribute(attribute)
value = read_attribute(attribute)
# Maintain nil value consistency with other adapters
value.presence && value.to_i
@@ -94,8 +92,8 @@ module Project::Storage
# Returns the total required disk space for all projects in bytes
def total_projects_size
Project.from("(#{Project.with_required_storage.to_sql}) sub")
.sum(:required_disk_space)
.to_i
.sum(:required_disk_space)
.to_i
end
private
+7 -3
View File
@@ -173,17 +173,21 @@ class Repository < ActiveRecord::Base
path
end
def required_disk_storage
##
# Update the required storage information, when necessary.
# Returns whether an asynchronous count refresh has been requested.
def update_required_storage
if scm.storage_available?
oldest_cachable_time = Setting.repository_storage_cache_minutes.to_i.minutes.ago
if storage_updated_at.nil? ||
storage_updated_at < oldest_cachable_time
Delayed::Job.enqueue ::Scm::StorageUpdaterJob.new(self)
return true
end
required_storage_bytes
end
false
end
# Finds and returns a revision with a number or the beginning of a hash
@@ -40,5 +40,5 @@ See doc/COPYRIGHT.rdoc for more details.
<%= render partial: 'projects/form/attributes/storage_field',
locals: { label: l(:label_total), value: storage['total'] } %>
<% end %>
<% end %>
</fieldset>
<% end %>
+14 -1
View File
@@ -28,7 +28,20 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<%= styled_form_tag({:action => 'edit', :tab => 'repositories'}) do %>
<section class="form--section">
<div class="form--field"><%= setting_check_box :autofetch_changesets %></div>
<div class="form--field">
<%= setting_check_box :autofetch_changesets %>
<div class="form--field-instructions">
<%= simple_format l('repositories.autofetch_information') %>
</div>
</div>
<div class="form--field">
<%= setting_text_field :repository_storage_cache_minutes,
unit: I18n.t(:label_minute_plural),
type: 'number' %>
<div class="form--field-instructions">
<%= simple_format l('repositories.storage.update_timeout') %>
</div>
</div>
<div class="form--field"><%= setting_check_box :sys_api_enabled,
:onclick => "if (this.checked) { Form.Element.enable('settings_sys_api_key'); } else { Form.Element.disable('settings_sys_api_key'); }" %>
<div class="form--field-instructions">
+4 -1
View File
@@ -1275,6 +1275,7 @@ en:
subproject_id: "Subproject"
repositories:
autofetch_information: "Check this if you want repositories to be updated automatically when accessing the repository module page.\nThis encompasses the retrieval of commits from the repository and refreshing the required disk storage."
checkout_instructions: "Checkout instructions"
create_managed_delay: "Please note: The repository is managed, it is created asynchronously on the disk and will be available shortly."
create_successful: "The repository has been registered."
@@ -1317,6 +1318,7 @@ en:
managed: "Create new repository in OpenProject"
storage:
not_available: "Disk storage consumption is not available for this repository."
update_timeout: "Keep the last required disk space information for a repository for N minutes.\nAs counting the required disk space of a repository may be costly, increase this value to reduce performance impact."
subversion:
existing_title: "Existing Subversion repository"
existing_introduction: "If you have an existing Subversion repository, you can link it with OpenProject to access it from within the application."
@@ -1337,7 +1339,7 @@ en:
setting_app_subtitle: "Application subtitle"
setting_app_title: "Application title"
setting_attachment_max_size: "Attachment max. size"
setting_autofetch_changesets: "Autofetch commits"
setting_autofetch_changesets: "Autofetch repository changes"
setting_autologin: "Autologin"
setting_available_languages: "Available languages"
setting_bcc_recipients: "Blind carbon copy recipients (bcc)"
@@ -1395,6 +1397,7 @@ en:
setting_protocol: "Protocol"
setting_repositories_encodings: "Repositories encodings"
setting_repository_authentication_caching_enabled: "Enable caching for authentication request of version control software"
setting_repository_storage_cache_minutes: "Repository disk size cache"
setting_repository_log_display_limit: "Maximum number of revisions displayed on file log"
setting_rest_api_enabled: "Enable REST web service"
setting_self_registration: "Self-registration"
-3
View File
@@ -278,9 +278,6 @@ journal_aggregation_time_minutes:
repository_storage_cache_minutes:
default: 720
format: int
project_storage_cache_minutes:
default: 60
format: int
api_max_page_size:
format: int
default: 500
+3
View File
@@ -362,6 +362,9 @@ module OpenProjectRepositoryAuthenticationSpecs
expect(repository.required_storage_bytes).to be == 0
request_storage
expect(response.code).to eq('200')
expect(response.body).to include('Updated: true')
repository.reload
expect(repository.required_storage_bytes).to be > 0
end
+8 -4
View File
@@ -22,7 +22,9 @@ shared_examples_for 'is a countable repository' do
it 'counts the repository storage automatically' do
expect(repository.required_storage_bytes).to be == 0
expect(repository.required_disk_storage).to be == count
expect(repository.update_required_storage).to be true
expect(repository.required_storage_bytes).to be == count
expect(repository.update_required_storage).to be false
expect(repository.storage_updated_at).to be >= 1.minute.ago
end
@@ -33,7 +35,8 @@ shared_examples_for 'is a countable repository' do
it 'sucessfuly updates the count to what the adapter returns' do
expect(repository.required_storage_bytes).to be == 0
expect(repository.required_disk_storage).to be == count
expect(repository.update_required_storage).to be true
expect(repository.required_storage_bytes).to be == count
end
end
end
@@ -41,8 +44,9 @@ shared_examples_for 'is a countable repository' do
context 'with real counter' do
it 'counts the repository storage automatically' do
expect(repository.required_storage_bytes).to be == 0
expect(repository.required_disk_storage).to be > 1.kilobyte
expect(repository.update_required_storage).to be true
expect(repository.storage_updated_at).to be >= 1.minute.ago
expect(repository.update_required_storage).to be false
end
end
end
@@ -54,6 +58,6 @@ shared_examples_for 'is not a countable repository' do
it 'does not return or update the count' do
expect(::Scm::StorageUpdaterJob).not_to receive(:new)
expect(repository.required_disk_storage).to be_nil
expect(repository.update_required_storage).to be false
end
end