Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-10 03:09:33 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-10 03:09:33 +0300
commit5a120c32fda1c88e38bbce056d6f30f4a2f41bc6 (patch)
tree8f5ef3c06e5f2f8707da5d32803d73fe10824ea5 /doc/development
parentb5944525b015e4efb4cd2c1d09ec37566d7691a0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'doc/development')
-rw-r--r--doc/development/README.md1
-rw-r--r--doc/development/documentation/index.md83
-rw-r--r--doc/development/transient/prevention-patterns.md132
3 files changed, 166 insertions, 50 deletions
diff --git a/doc/development/README.md b/doc/development/README.md
index d73acdd9dbc..5db4c5438c4 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -294,6 +294,7 @@ See [database guidelines](database/index.md).
- [Compatibility with multiple versions of the application running at the same time](multi_version_compatibility.md)
- [Features inside `.gitlab/`](features_inside_dot_gitlab.md)
- [Dashboards for stage groups](stage_group_dashboards.md)
+- [Preventing transient bugs](transient/prevention-patterns.md)
## Other GitLab Development Kit (GDK) guides
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index b878f0fc1ce..6b30a6dab5d 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -328,68 +328,51 @@ with GitLab 11.4. Meaning, it's available only with `/help` from GitLab
### Linking to `/help`
-When you're building a new feature, you may need to link the documentation
-from GitLab, the application. This is normally done in files inside the
-`app/views/` directory with the help of the `help_page_path` helper method.
+When you're building a new feature, you may need to link to the documentation
+from the GitLab application. This is normally done in files inside the
+`app/views/` directory, with the help of the `help_page_path` helper method.
-In its simplest form, the HAML code to generate a link to the `/help` page is:
+The `help_page_path` contains the path to the document you want to link to,
+with the following conventions:
-```haml
-= link_to 'Help page', help_page_path('user/permissions')
-```
-
-The `help_page_path` contains the path to the document you want to link to with
-the following conventions:
-
-- it is relative to the `doc/` directory in the GitLab repository
-- the `.md` extension must be omitted
-- it must not end with a slash (`/`)
-
-Below are some special cases where should be used depending on the context.
-You can combine one or more of the following:
-
-1. **Linking to an anchor link.** Use `anchor` as part of the `help_page_path`
- method:
+- It's relative to the `doc/` directory in the GitLab repository.
+- It omits the `.md` extension.
+- It doesn't end with a slash (`/`).
- ```haml
- = link_to 'Help page', help_page_path('user/permissions', anchor: 'anchor-link')
- ```
+The help text follows the [Pajamas guidelines](https://design.gitlab.com/usability/helping-users/#formatting-help-content).
-1. **Opening links in a new tab.** This should be the default behavior:
+Use the following special cases depending on the context, ensuring all links
+are inside `_()` so they can be translated:
- ```haml
- = link_to 'Help page', help_page_path('user/permissions'), target: '_blank'
- ```
+- Linking to a doc page. In its most basic form, the HAML code to generate a
+ link to the `/help` page is:
-1. **Using a question icon.** Usually used in settings where a long
- description cannot be used, like near checkboxes. You can basically use
- any GitLab SVG icon, but prefer the `question-o`:
-
- ```haml
- = link_to sprite_icon('question-o'), help_page_path('user/permissions')
- ```
+ ```haml
+ = link_to _('Learn more.'), help_page_path('user/permissions'), target: '_blank', rel: 'noopener noreferrer'
+ ```
-1. **Using a button link.** Useful in places where text would be out of context
- with the rest of the page layout:
+- Linking to an anchor link. Use `anchor` as part of the `help_page_path`
+ method:
- ```haml
- = link_to 'Help page', help_page_path('user/permissions'), class: 'btn btn-info'
- ```
+ ```haml
+ = link_to _('Learn more.'), help_page_path('user/permissions', anchor: 'anchor-link'), target: '_blank', rel: 'noopener noreferrer'
+ ```
-1. **Using links inline of some text.**
+- Using links inline of some text. First, define the link, and then use it. In
+ this example, `link_start` is the name of the variable that contains the
+ link:
- ```haml
- Description to #{link_to 'Help page', help_page_path('user/permissions')}.
- ```
+ ```haml
+ - link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/permissions') }
+ %p= _("This is a text describing the option/feature in a sentence. %{link_start}Learn more.%{link_end}").html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ ```
-1. **Adding a period at the end of the sentence.** Useful when you don't want
- the period to be part of the link:
+- Using a button link. Useful in places where text would be out of context with
+ the rest of the page layout:
- ```haml
- = succeed '.' do
- Learn more in the
- = link_to 'Help page', help_page_path('user/permissions')
- ```
+ ```haml
+ = link_to _('Learn more.'), help_page_path('user/permissions'), class: 'btn btn-info', target: '_blank', rel: 'noopener noreferrer'
+ ```
#### Linking to `/help` in JavaScript
diff --git a/doc/development/transient/prevention-patterns.md b/doc/development/transient/prevention-patterns.md
new file mode 100644
index 00000000000..7231562415b
--- /dev/null
+++ b/doc/development/transient/prevention-patterns.md
@@ -0,0 +1,132 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Preventing Transient Bugs
+
+This page will cover architectural patterns and tips for developers to follow to prevent [transient bugs.](https://about.gitlab.com/handbook/engineering/quality/issue-triage/#transient-bugs)
+
+## Frontend
+
+### Don't rely on response order
+
+When working with multiple requests, it's easy to assume the order of the responses will match the order in which they are triggered.
+
+That's not always the case and can cause bugs that only happen if the order is switched.
+
+**Example:**
+
+- `diffs_metadata.json` (lighter)
+- `diffs_batch.json` (heavier)
+
+If your feature requires data from both, ensure that the two have finished loading before working on it.
+
+### Simulate slower connections when testing manually
+
+Add a network condition template to your browser's dev tools to enable you to toggle between a slow and a fast connection.
+
+**Example:**
+
+- Turtle:
+ - Down: 50kb/s
+ - Up: 20kb/s
+ - Latency: 10000ms
+
+### Collapsed elements
+
+When setting event listeners, if not possible to use event delegation, ensure all relevant event listeners are set for expanded content.
+
+Including when that expanded content is:
+
+- **Invisible** (`display: none;`). Some JavaScript requires the element to be visible to work properly (eg.: when taking measurements).
+- **Dynamic content** (AJAX/DOM manipulation).
+
+### Using assertions to detect transient bugs caused by unmet conditions
+
+Transient bugs happen in the context of code that executes under the assumption
+that the application’s state meets one or more conditions. We may write a feature
+that assumes a server-side API response always include a group of attributes or that
+an operation only executes when the application has successfully transitioned to a new
+state.
+
+Transient bugs are difficult to debug because there isn’t any mechanism that alerts
+the user or the developer about unsatisfied conditions. These conditions are usually
+not expressed explicitly in the code. A useful debugging technique for such situations
+is placing assertions to make any assumption explicit. They can help detect the cause
+which unmet condition causes the bug.
+
+#### Asserting pre-conditions on state mutations
+
+A common scenario that leads to transient bugs is when there is a polling service
+that should mutate state only if a user operation is completed. We can use
+assertions to make this pre-condition explicit:
+
+```javascript
+// This action is called by a polling service. It assumes that all pre-conditions
+// are satisfied by the time the action is dispatched.
+export const updateMergeableStatus = ({ commit }, payload) => {
+ commit(types.SET_MERGEABLE_STATUS, payload);
+};
+
+// We can make any pre-condition explicit by adding an assertion
+export const updateMergeableStatus = ({ state, commit }, payload) => {
+ console.assert(
+ state.isResolvingDiscussion === true,
+ 'Resolve discussion request must be completed before updating mergeable status'
+ );
+ commit(types.SET_MERGEABLE_STATUS, payload);
+};
+```
+
+#### Asserting API contracts
+
+Another useful way of using assertions is to detect if the response payload returned
+by the server-side endpoint satisfies the API contract.
+
+#### Related reading
+
+[Debug it!](https://pragprog.com/titles/pbdp/debug-it/) explores techniques to diagnose
+and fix non-determinstic bugs and write software that is easier to debug.
+
+## Backend
+
+### Sidekiq jobs with locks
+
+When dealing with asynchronous work via Sidekiq, it is possible to have 2 jobs with the same arguments
+getting worked on at the same time. If not handled correctly, this can result in an outdated or inaccurate state.
+
+For instance, consider a worker that updates a state of an object. Before the worker updates the state
+(for example, `#update_state`) of the object, it needs to check what the appropriate state should be
+(for example, `#check_state`).
+
+When there are 2 jobs being worked on at the same time, it is possible that the order of operations will go like:
+
+1. (Worker A) Calls `#check_state`
+1. (Worker B) Calls `#check_state`
+1. (Worker B) Calls `#update_state`
+1. (Worker A) Calls `#update_state`
+
+In this example, `Worker B` is meant to set the updated status. But `Worker A` calls `#update_state` a little too late.
+
+This can be avoided by utilizing either database locks or `Gitlab::ExclusiveLease`. This way, jobs will be
+worked on one at a time. This also allows them to be marked as [idempotent](../sidekiq_style_guide.md#idempotent-jobs).
+
+### Retry mechanism handling
+
+There are times that an object/record will be on a failed state which can be rechecked.
+
+If an object is in a state that can be rechecked, ensure that appropriate messaging is shown to the user
+so they know what to do. Also, make sure that the retry functionality will be able to reset the state
+correctly when triggered.
+
+### Error Logging
+
+Error logging doesn't necessarily directly prevents transient bugs but it can help to debug them.
+
+When coding, sometimes we expect some exceptions to be raised and we rescue them.
+
+Logging whenever we rescue an error helps in case it's causing transient bugs that a user may see.
+While investigating a bug report, it may require the engineer to look into logs of when it happened.
+Seeing an error being logged can be a signal of something that went wrong which can be handled differently.