summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/commits.js5
-rw-r--r--app/assets/javascripts/diffs/components/diff_gutter_avatars.vue5
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js15
-rw-r--r--app/assets/javascripts/lib/utils/text_utility.js8
-rw-r--r--app/assets/stylesheets/framework/tooltips.scss5
-rw-r--r--app/assets/stylesheets/framework/variables_overrides.scss4
-rw-r--r--app/views/peek/views/_gc.html.haml7
-rw-r--r--app/views/peek/views/_redis.html.haml7
-rw-r--r--app/views/peek/views/_sidekiq.html.haml7
-rw-r--r--changelogs/unreleased/ab-count-strategies.yml5
-rw-r--r--doc/development/chaos_endpoints.md8
-rw-r--r--doc/development/reusing_abstractions.md11
-rw-r--r--lib/gitlab/database/count.rb12
-rw-r--r--lib/gitlab/database/count/exact_count_strategy.rb4
-rw-r--r--lib/gitlab/database/count/reltuples_count_strategy.rb4
-rw-r--r--lib/gitlab/database/count/tablesample_count_strategy.rb4
-rw-r--r--locale/gitlab.pot16
-rw-r--r--spec/frontend/lib/utils/text_utility_spec.js14
-rw-r--r--spec/lib/gitlab/database/count/exact_count_strategy_spec.rb14
-rw-r--r--spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb14
-rw-r--r--spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb18
-rw-r--r--spec/lib/gitlab/database/count_spec.rb15
22 files changed, 48 insertions, 154 deletions
diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js
index 54e2589c707..7dd75d03ab9 100644
--- a/app/assets/javascripts/commits.js
+++ b/app/assets/javascripts/commits.js
@@ -1,5 +1,5 @@
import $ from 'jquery';
-import { pluralize } from './lib/utils/text_utility';
+import { n__ } from '~/locale';
import { localTimeAgo } from './lib/utils/datetime_utility';
import Pager from './pager';
import axios from './lib/utils/axios_utils';
@@ -90,9 +90,10 @@ export default class CommitsList {
.first()
.find('li.commit').length,
);
+
$commitsHeadersLast
.find('span.commits-count')
- .text(`${commitsCount} ${pluralize('commit', commitsCount)}`);
+ .text(n__('%d commit', '%d commits', commitsCount));
}
localTimeAgo($processedData.find('.js-timeago'));
diff --git a/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue b/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue
index af5550aec3b..7ede7a4f430 100644
--- a/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue
+++ b/app/assets/javascripts/diffs/components/diff_gutter_avatars.vue
@@ -1,6 +1,7 @@
<script>
+import { n__ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
-import { pluralize, truncate } from '~/lib/utils/text_utility';
+import { truncate } from '~/lib/utils/text_utility';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import { GlTooltipDirective } from '@gitlab/ui';
import { COUNT_OF_AVATARS_IN_GUTTER, LENGTH_OF_AVATAR_TOOLTIP } from '../constants';
@@ -42,7 +43,7 @@ export default {
return '';
}
- return pluralize(`${this.moreCount} more comment`, this.moreCount);
+ return n__('%d more comment', '%d more comments', this.moreCount);
},
},
methods: {
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index 062d21ed247..a4715789337 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -2,8 +2,7 @@ import $ from 'jquery';
import _ from 'underscore';
import timeago from 'timeago.js';
import dateFormat from 'dateformat';
-import { pluralize } from './text_utility';
-import { languageCode, s__, __ } from '../../locale';
+import { languageCode, s__, __, n__ } from '../../locale';
window.timeago = timeago;
@@ -231,14 +230,10 @@ export const timeIntervalInWords = intervalInSeconds => {
const secondsInteger = parseInt(intervalInSeconds, 10);
const minutes = Math.floor(secondsInteger / 60);
const seconds = secondsInteger - minutes * 60;
- let text = '';
-
- if (minutes >= 1) {
- text = `${minutes} ${pluralize('minute', minutes)} ${seconds} ${pluralize('second', seconds)}`;
- } else {
- text = `${seconds} ${pluralize('second', seconds)}`;
- }
- return text;
+ const secondsText = n__('%d second', '%d seconds', seconds);
+ return minutes >= 1
+ ? [n__('%d minute', '%d minutes', minutes), secondsText].join(' ')
+ : secondsText;
};
export const dateInWords = (date, abbreviated = false, hideYear = false) => {
diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js
index d38f59b5861..d13fbeb5fc7 100644
--- a/app/assets/javascripts/lib/utils/text_utility.js
+++ b/app/assets/javascripts/lib/utils/text_utility.js
@@ -29,14 +29,6 @@ export const humanize = string =>
string.charAt(0).toUpperCase() + string.replace(/_/g, ' ').slice(1);
/**
- * Adds an 's' to the end of the string when count is bigger than 0
- * @param {String} str
- * @param {Number} count
- * @returns {String}
- */
-export const pluralize = (str, count) => str + (count > 1 || count === 0 ? 's' : '');
-
-/**
* Replaces underscores with dashes
* @param {*} str
* @returns {String}
diff --git a/app/assets/stylesheets/framework/tooltips.scss b/app/assets/stylesheets/framework/tooltips.scss
index 98f28987a82..edc2fb532c8 100644
--- a/app/assets/stylesheets/framework/tooltips.scss
+++ b/app/assets/stylesheets/framework/tooltips.scss
@@ -1,7 +1,6 @@
.tooltip-inner {
- font-size: $tooltip-font-size;
+ font-size: $gl-font-size-small;
border-radius: $border-radius-default;
- line-height: 16px;
+ line-height: $gl-line-height;
font-weight: $gl-font-weight-normal;
- padding: 8px;
}
diff --git a/app/assets/stylesheets/framework/variables_overrides.scss b/app/assets/stylesheets/framework/variables_overrides.scss
index ea96381a098..604b48e11ab 100644
--- a/app/assets/stylesheets/framework/variables_overrides.scss
+++ b/app/assets/stylesheets/framework/variables_overrides.scss
@@ -48,3 +48,7 @@ $spacers: (
9: ($spacer * 8)
);
$pagination-color: $gl-text-color;
+$tooltip-padding-y: 0.5rem;
+$tooltip-padding-x: 0.75rem;
+$tooltip-arrow-height: 0.5rem;
+$tooltip-arrow-width: 1rem;
diff --git a/app/views/peek/views/_gc.html.haml b/app/views/peek/views/_gc.html.haml
deleted file mode 100644
index 2a586261ce1..00000000000
--- a/app/views/peek/views/_gc.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-- local_assigns.fetch(:view)
-
-%span.bold
- %span{ title: _('Invoke Time'), data: { defer_to: "#{view.defer_key}-gc_time" } }...
- \/
- %span{ title: _('Invoke Count'), data: { defer_to: "#{view.defer_key}-invokes" } }...
-gc
diff --git a/app/views/peek/views/_redis.html.haml b/app/views/peek/views/_redis.html.haml
deleted file mode 100644
index f7fba6c95fc..00000000000
--- a/app/views/peek/views/_redis.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-- local_assigns.fetch(:view)
-
-%span.bold
- %span{ data: { defer_to: "#{view.defer_key}-duration" } }...
- \/
- %span{ data: { defer_to: "#{view.defer_key}-calls" } }...
-redis
diff --git a/app/views/peek/views/_sidekiq.html.haml b/app/views/peek/views/_sidekiq.html.haml
deleted file mode 100644
index 7efbc05890d..00000000000
--- a/app/views/peek/views/_sidekiq.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-- local_assigns.fetch(:view)
-
-%span.bold
- %span{ data: { defer_to: "#{view.defer_key}-duration" } }...
- \/
- %span{ data: { defer_to: "#{view.defer_key}-calls" } }...
-sidekiq
diff --git a/changelogs/unreleased/ab-count-strategies.yml b/changelogs/unreleased/ab-count-strategies.yml
new file mode 100644
index 00000000000..bd95ff45d6f
--- /dev/null
+++ b/changelogs/unreleased/ab-count-strategies.yml
@@ -0,0 +1,5 @@
+---
+title: Use tablesample approximate counting by default.
+merge_request: 31048
+author:
+type: performance
diff --git a/doc/development/chaos_endpoints.md b/doc/development/chaos_endpoints.md
index eb6dde2d24e..961520db7d8 100644
--- a/doc/development/chaos_endpoints.md
+++ b/doc/development/chaos_endpoints.md
@@ -69,7 +69,7 @@ curl http://localhost:3000/-/chaos/leakmem?memory_mb=1024&duration_s=10&token=se
This endpoint attempts to fully utilise a single core, at 100%, for the given period.
-Depending on your rack server setup, your request may timeout after a predermined period (normally 60 seconds).
+Depending on your rack server setup, your request may timeout after a predetermined period (normally 60 seconds).
If you're using Unicorn, this is done by killing the worker process.
```
@@ -80,7 +80,7 @@ GET /-/chaos/cpu_spin?duration_s=50&async=true
| Attribute | Type | Required | Description |
| ------------ | ------- | -------- | --------------------------------------------------------------------- |
-| `duration_s` | integer | no | Duration, in seconds, that the core will be utilised. Defaults to 30s |
+| `duration_s` | integer | no | Duration, in seconds, that the core will be utilized. Defaults to 30s |
| `async` | boolean | no | Set to true to consume CPU in a Sidekiq background worker process |
```bash
@@ -93,7 +93,7 @@ curl http://localhost:3000/-/chaos/cpu_spin?duration_s=60&token=secret
This endpoint attempts to fully utilise a single core, and interleave it with DB request, for the given period.
This endpoint can be used to model yielding execution to another threads when running concurrently.
-Depending on your rack server setup, your request may timeout after a predermined period (normally 60 seconds).
+Depending on your rack server setup, your request may timeout after a predetermined period (normally 60 seconds).
If you're using Unicorn, this is done by killing the worker process.
```
@@ -105,7 +105,7 @@ GET /-/chaos/db_spin?duration_s=50&async=true
| Attribute | Type | Required | Description |
| ------------ | ------- | -------- | --------------------------------------------------------------------------- |
| `interval_s` | float | no | Interval, in seconds, for every DB request. Defaults to 1s |
-| `duration_s` | integer | no | Duration, in seconds, that the core will be utilised. Defaults to 30s |
+| `duration_s` | integer | no | Duration, in seconds, that the core will be utilized. Defaults to 30s |
| `async` | boolean | no | Set to true to perform the operation in a Sidekiq background worker process |
```bash
diff --git a/doc/development/reusing_abstractions.md b/doc/development/reusing_abstractions.md
index 59da02ed6fd..fce144f8dc2 100644
--- a/doc/development/reusing_abstractions.md
+++ b/doc/development/reusing_abstractions.md
@@ -14,13 +14,13 @@ on maintainability, the ability to easily debug problems, or even performance.
An example would be to use `ProjectsFinder` in `IssuesFinder` to limit issues to
those belonging to a set of projects. While initially this may seem like a good
idea, both classes provide a very high level interface with very little control.
-This means that `IssuesFinder` may not be able to produce a better optimised
+This means that `IssuesFinder` may not be able to produce a better optimized
database query, as a large portion of the query is controlled by the internals
of `ProjectsFinder`.
To work around this problem, you would use the same code used by
`ProjectsFinder`, instead of using `ProjectsFinder` itself directly. This allows
-you to compose your behaviour better, giving you more control over the behaviour
+you to compose your behavior better, giving you more control over the behavior
of the code.
To illustrate, consider the following code from `IssuableFinder#projects`:
@@ -52,7 +52,7 @@ functionality is added to this (high level) interface. Instead of _only_
affecting the cases where this is necessary, it may also start affecting
`IssuableFinder` in a negative way. For example, the query produced by
`GroupProjectsFinder` may include unnecessary conditions. Since we're using a
-finder here, we can't easily opt-out of that behaviour. We could add options to
+finder here, we can't easily opt-out of that behavior. We could add options to
do so, but then we'd need as many options as we have features. Every option adds
two code paths, which means that for four features we have to cover 8 different
code paths.
@@ -213,6 +213,5 @@ The API provided by Active Record itself, such as the `where` method, `save`,
Everything in `app/workers`.
-The scheduling of Sidekiq jobs using `SomeWorker.perform_async`, `perform_in`,
-etc. Directly invoking a worker using `SomeWorker.new.perform` should be avoided
-at all times in application code, though this is fine to use in tests.
+Use `SomeWorker.perform_async` or `SomeWorker.perform_in` to schedule Sidekiq
+jobs. Never directly invoke a worker using `SomeWorker.new.perform`.
diff --git a/lib/gitlab/database/count.rb b/lib/gitlab/database/count.rb
index f3d37ccd72a..eac61254bdf 100644
--- a/lib/gitlab/database/count.rb
+++ b/lib/gitlab/database/count.rb
@@ -37,16 +37,14 @@ module Gitlab
# @return [Hash] of Model -> count mapping
def self.approximate_counts(models, strategies: [TablesampleCountStrategy, ReltuplesCountStrategy, ExactCountStrategy])
strategies.each_with_object({}) do |strategy, counts_by_model|
- if strategy.enabled?
- models_with_missing_counts = models - counts_by_model.keys
+ models_with_missing_counts = models - counts_by_model.keys
- break counts_by_model if models_with_missing_counts.empty?
+ break counts_by_model if models_with_missing_counts.empty?
- counts = strategy.new(models_with_missing_counts).count
+ counts = strategy.new(models_with_missing_counts).count
- counts.each do |model, count|
- counts_by_model[model] = count
- end
+ counts.each do |model, count|
+ counts_by_model[model] = count
end
end
end
diff --git a/lib/gitlab/database/count/exact_count_strategy.rb b/lib/gitlab/database/count/exact_count_strategy.rb
index fa6951eda22..0b8fe640bf8 100644
--- a/lib/gitlab/database/count/exact_count_strategy.rb
+++ b/lib/gitlab/database/count/exact_count_strategy.rb
@@ -23,10 +23,6 @@ module Gitlab
rescue *CONNECTION_ERRORS
{}
end
-
- def self.enabled?
- true
- end
end
end
end
diff --git a/lib/gitlab/database/count/reltuples_count_strategy.rb b/lib/gitlab/database/count/reltuples_count_strategy.rb
index 695f6fa766e..6cd90c01ab2 100644
--- a/lib/gitlab/database/count/reltuples_count_strategy.rb
+++ b/lib/gitlab/database/count/reltuples_count_strategy.rb
@@ -31,10 +31,6 @@ module Gitlab
{}
end
- def self.enabled?
- Gitlab::Database.postgresql?
- end
-
private
# Models using single-type inheritance (STI) don't work with
diff --git a/lib/gitlab/database/count/tablesample_count_strategy.rb b/lib/gitlab/database/count/tablesample_count_strategy.rb
index 7777f31f702..e9387a91a14 100644
--- a/lib/gitlab/database/count/tablesample_count_strategy.rb
+++ b/lib/gitlab/database/count/tablesample_count_strategy.rb
@@ -28,10 +28,6 @@ module Gitlab
{}
end
- def self.enabled?
- Gitlab::Database.postgresql? && Feature.enabled?(:tablesample_counts)
- end
-
private
def perform_count(model, estimate)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 7b1a3fd4d2c..9607be988be 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -95,11 +95,21 @@ msgid_plural "%d metrics"
msgstr[0] ""
msgstr[1] ""
+msgid "%d minute"
+msgid_plural "%d minutes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d more comment"
msgid_plural "%d more comments"
msgstr[0] ""
msgstr[1] ""
+msgid "%d second"
+msgid_plural "%d seconds"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d staged change"
msgid_plural "%d staged changes"
msgstr[0] ""
@@ -5696,12 +5706,6 @@ msgstr ""
msgid "Invocations"
msgstr ""
-msgid "Invoke Count"
-msgstr ""
-
-msgid "Invoke Time"
-msgstr ""
-
msgid "IssuableStatus|Closed (%{moved_link_start}moved%{moved_link_end})"
msgstr ""
diff --git a/spec/frontend/lib/utils/text_utility_spec.js b/spec/frontend/lib/utils/text_utility_spec.js
index dc886d0db3b..b6f1aef9ce4 100644
--- a/spec/frontend/lib/utils/text_utility_spec.js
+++ b/spec/frontend/lib/utils/text_utility_spec.js
@@ -29,20 +29,6 @@ describe('text_utility', () => {
});
});
- describe('pluralize', () => {
- it('should pluralize given string', () => {
- expect(textUtils.pluralize('test', 2)).toBe('tests');
- });
-
- it('should pluralize when count is 0', () => {
- expect(textUtils.pluralize('test', 0)).toBe('tests');
- });
-
- it('should not pluralize when count is 1', () => {
- expect(textUtils.pluralize('test', 1)).toBe('test');
- });
- });
-
describe('dasherize', () => {
it('should replace underscores with dashes', () => {
expect(textUtils.dasherize('foo_bar_foo')).toEqual('foo-bar-foo');
diff --git a/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb b/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb
index 3991c737a26..0c1be4b4610 100644
--- a/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb
+++ b/spec/lib/gitlab/database/count/exact_count_strategy_spec.rb
@@ -23,18 +23,4 @@ describe Gitlab::Database::Count::ExactCountStrategy do
expect(subject).to eq({})
end
end
-
- describe '.enabled?' do
- it 'is enabled for PostgreSQL' do
- allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
-
- expect(described_class.enabled?).to be_truthy
- end
-
- it 'is enabled for MySQL' do
- allow(Gitlab::Database).to receive(:postgresql?).and_return(false)
-
- expect(described_class.enabled?).to be_truthy
- end
- end
end
diff --git a/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb b/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb
index bd3c66d0548..a528707c9dc 100644
--- a/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb
+++ b/spec/lib/gitlab/database/count/reltuples_count_strategy_spec.rb
@@ -48,18 +48,4 @@ describe Gitlab::Database::Count::ReltuplesCountStrategy do
end
end
end
-
- describe '.enabled?' do
- it 'is enabled for PostgreSQL' do
- allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
-
- expect(described_class.enabled?).to be_truthy
- end
-
- it 'is disabled for MySQL' do
- allow(Gitlab::Database).to receive(:postgresql?).and_return(false)
-
- expect(described_class.enabled?).to be_falsey
- end
- end
end
diff --git a/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb b/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb
index 40d810b195b..a57f033b5ed 100644
--- a/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb
+++ b/spec/lib/gitlab/database/count/tablesample_count_strategy_spec.rb
@@ -56,22 +56,4 @@ describe Gitlab::Database::Count::TablesampleCountStrategy do
end
end
end
-
- describe '.enabled?' do
- before do
- stub_feature_flags(tablesample_counts: true)
- end
-
- it 'is enabled for PostgreSQL' do
- allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
-
- expect(described_class.enabled?).to be_truthy
- end
-
- it 'is disabled for MySQL' do
- allow(Gitlab::Database).to receive(:postgresql?).and_return(false)
-
- expect(described_class.enabled?).to be_falsey
- end
- end
end
diff --git a/spec/lib/gitlab/database/count_spec.rb b/spec/lib/gitlab/database/count_spec.rb
index 1d096b8fa7c..71d6633f62f 100644
--- a/spec/lib/gitlab/database/count_spec.rb
+++ b/spec/lib/gitlab/database/count_spec.rb
@@ -9,24 +9,13 @@ describe Gitlab::Database::Count do
let(:models) { [Project, Identity] }
context '.approximate_counts' do
- context 'selecting strategies' do
- let(:strategies) { [double('s1', enabled?: true), double('s2', enabled?: false)] }
-
- it 'uses only enabled strategies' do
- expect(strategies[0]).to receive(:new).and_return(double('strategy1', count: {}))
- expect(strategies[1]).not_to receive(:new)
-
- described_class.approximate_counts(models, strategies: strategies)
- end
- end
-
context 'fallbacks' do
subject { described_class.approximate_counts(models, strategies: strategies) }
let(:strategies) do
[
- double('s1', enabled?: true, new: first_strategy),
- double('s2', enabled?: true, new: second_strategy)
+ double('s1', new: first_strategy),
+ double('s2', new: second_strategy)
]
end