GitLab의 개발에서의 기능 플래그

참고: 이 문서는 GitLab 제품의 개발 및 운영에 기여하는 방법을 설명합니다. 자신의 응용 프로그램에서 기능 플래그를 사용하여 기능을 표시하거나 숨기려면 대신 이 기능 플래그 정보를 참조하세요.

경고: 새롭게 도입된 기능 플래그는 기본적으로 비활성화되어야 합니다.

경고: 새롭게 도입된 기능 플래그는 액터와 함께 사용되어야 합니다.

디자인 문서:

이 문서는 기능 플래그의 내부 사용을 개선하기 위한 에픽의 일환으로 계속해서 작업되고 있습니다. 새로운 문제로 제안 사항을 제출하고 해당 에픽과 연결하십시오.

기능 플래그 라이프사이클에 대한 개요 또는 기능 플래그를 사용해야 하는지 여부를 결정하는 데 도움이 필요한 경우에는 기능 플래그 라이프사이클 핸드북 페이지를 참조하십시오.

기능 플래그를 사용해야 하는 시기

핸드북의 “기능 플래그를 사용해야 하는 시기” 섹션으로 이동하였습니다.

기간이 긴 설정에는 기능 플래그를 사용하지 마십시오

기능 플래그는 짧은 기간 동안 사용할 목적으로 만들어졌습니다. 사용자/그룹/프로젝트별로 오랜 기간동안 활성화되어야 하는 기능 플래그를 추가하려면 Cascading Settings 또는 Application Settings 등을 도입하는 것이 좋습니다. 설정을 사용하면 GitLab.com 또는 자체 관리형 버전에서 고객이 필요에 따라 기능을 활성화하거나 비활성화할 수 있습니다. GitLab.com에서 사용자는 기능 플래그를 직접 활성화하거나 비활성화할 수 없으며 자체 관리형 관리자만이 기능 플래그를 변경할 수 있습니다. 또한 GitLab Dedicated에서는 기능 플래그가 지원되지 않는데, 이는 설정의 대체로 사용해서는 안 된다는 또 다른 이유입니다.

GitLab 개발에서의 기능 플래그

기능 플래그를 사용할지 결정할 때 고려해야 할 주요 사항은 다음과 같습니다:

  • 기능 플래그는 기본적으로 비활성화 되어 있어야 합니다.
  • 기능 플래그는 기능 플래그 관리에 대한 요구를 줄이기 위해 가능한 한 짧은 기간동안 코드베이스에 유지되어야 합니다.
  • 기능 플래그를 사용하는 사람은 기능 플래그 뒤에 있는 기능의 상태를 문서와 다른 이해 관계자들에게 명확하게 전달하는 책임이 있습니다. 기능 플래그가 필요하다는 것이 명백해지면 이슈 설명을 기능 플래그 이름으로 업데이트하고 기본값이 활성화되었는지 비활성화되었는지 전달해야 합니다.
  • 새로운 기능 플래그를 도입하거나 상태를 업데이트하거나 안정적인 기능이라고 판단되어 기존 기능을 삭제하는 합병 요청에는 반드시 ~"feature flag" 레이블을 할당해야 합니다.

기능 구현이 여러 합병 요청을 통해 제공될 때:

  1. 첫 번째 기능 플래그를 기본적으로 비활성화된 상태로 첫 번째 합병 요청에서 사용합니다. 기능은 별도로 추가하면 안 됩니다.
  2. 하나 이상의 합병 요청을 통해 점진적인 변경 사항을 제출하면서 새로 추가된 코드를 기능 플래그가 활성화된 경우에만 도달할 수 있도록 합니다. 개발 과정에서 로컬 GDK에서 기능 플래그를 활성화한 상태로 유지할 수 있습니다.
  3. 기능이 다른 팀원들에 의해 테스트될 준비가 되면 초기 문서를 작성합니다. 기능 플래그에 관한 상태에 대한 세부 정보를 포함합니다.
  4. 특정 그룹/프로젝트/사용자를 대상으로 기능 플래그를 활성화하고 구현에 문제가 없는지 확인합니다. 문서가 없으면 gitlab-org/gitlab와 같은 공개 프로젝트에 기능 플래그를 활성화하지 않으십시오. 공개 프로젝트에서 기능이 활성화되어 있는 것을 보면 팀원 및 기여자들이 그 기능의 사용법에 대한 문서를 찾을 수 있습니다.
  5. 기능이 자체 관리형 인스턴스를 포함하여 제품용으로 준비된 상태라면, 다음과 같은 목적으로 한 합병 요청을 엽니다:
    • 최신 플래그 상태를 설명하는 문서를 업데이트합니다.
    • 변경 로그 항목을 추가합니다.
    • 새로운 동작을 활성화하기 위해 기능 플래그를 제거하거나 기능 플래그를 기본적으로 활성화로 전환합니다(이는opsbeta 기능 플래그에만 해당됩니다).

기능 플래그 제거가 여러 합병 요청을 통해 제공될 때:

  1. 기능 플래그의 값 변경은 합병 요청에서 유일한 변경 사항이어야 합니다. 기능 플래그가 코드베이스에 존재하는 한 두 상태가 모두 완전히 기능성이 있어야 합니다(기능이 켜거나 꺼진 경우).
  2. 기능 플래그에 대한 모든 언급을 제거한 후에 레거시 코드를 제거할 수 있습니다. 기능 플래그 Roll-out 이슈의 단계를 따르고 단계를 건너뛰어야 하는 경우에는 해당 이슈에 왜 그런지에 대한 코멘트를 추가해야 합니다.

기능 플래그가 기능의 릴리스를 하나의 월(= 하나의 릴리스)만큼 적어도 지연시킬 것이라고 생각할지도 모릅니다. 하지만 실제로는 그렇지 않습니다. 기능 플래그는 특정 기간(예: 적어도 한 릴리스) 동안 존재해야 하는 게 아니라 안정적인 기능이 될 때까지 존재해야 합니다. 안정적이라 함은 GitLab.com에서 장애와 같은 문제를 발생시키지 않고 작동한다는 것을 의미합니다.

깨진 기본 브랜치의 위험

기능 플래그는 도입된 MR에서 사용되어야 합니다. 그렇지 않으면 기본 브랜치에서만 실행되는 rspec:feature-flags 작업으로 깨진 기본 브랜치 시나리오가 발생합니다.

기능 플래그 유형

예상된 사용 사례와 일치하는 기능 플래그 유형을 선택하세요.

gitlab_com_derisk 유형

gitlab_com_derisk 기능 플래그는 GitLab.com 배포의 위험을 줄이기 위해 사용되는 단명한 기능 플래그입니다. GitLab에서 사용하는 대부분의 기능 플래그는 gitlab_com_derisk 유형입니다.

Constraints

  • default_enabled: 반드시 true로 설정되어선 안 됩니다. 이 유형의 기능 플래그는 GitLab.com의 위험을 줄이기 위한 것이므로, GitLab.com에서 활성화된 후에 코드베이스에 해당 기능 플래그를 유지할 필요가 없습니다. 이 유형의 기능 플래그에 대해 default_enabled: true는 어떠한 효과도 발휘하지 않을 것입니다.
  • 최대 수명: 기본 브랜치에 병합된 후 2개월
  • 문서: 이 유형의 기능 플래그는 단명하고 배포 관련되어 있기 때문에 GitLab의 모든 기능 플래그 페이지에 문서화될 필요가 없습니다.
  • 롤아웃 이슈: 기능 플래그 롤아웃 템플릿에서 생성된 롤아웃 이슈가 있어야 합니다.

사용법

gitlab_com_derisk 유형의 기능 플래그 형식은 Feature.<state>(:<dev_flag_name>)입니다.

이를 활성화하거나 비활성화하기 위해서는 GitLab Rails 콘솔에서 다음을 실행하세요:

# 인스턴스에 대해 활성화:
Feature.enable(:<dev_flag_name>)

# 인스턴스에 대해 비활성화:
Feature.disable(:<dev_flag_name>)

# 특정 프로젝트에 대해 활성화:
Feature.enable(:<dev_flag_name>, Project.find(<project id>))

# 특정 프로젝트에 대해 비활성화:
Feature.disable(:<dev_flag_name>, Project.find(<project id>))

gitlab_com_derisk 유형의 기능 플래그 상태를 확인하려면:

# 기능 플래그가 활성화되었는지 확인
Feature.enabled?(:dev_flag_name)

# 기능 플래그가 비활성화되었는지 확인
Feature.disabled?(:dev_flag_name)

wip 유형

일부 기능은 복잡하여 여러 MR을 통해 구현해야 할 수 있습니다. 완전히 구현되기 전까지 아무도 그것을 볼 수 없도록 숨겨져 있어야 합니다. 이러한 경우, wip (작업 진행 중) 기능 플래그를 사용하면 모든 변경 사항을 본 브랜치에 병합할 수 있게 됩니다만 실제로는 아직 해당 기능을 사용하지는 않을 것입니다.

기능이 완료되면, 기능 플래그 유형은 기능이 어떻게 고객에게 제시/문서화될지에 따라 gitlab_com_derisk 또는 beta 유형으로 변경될 수 있습니다.

Constraints

  • default_enabled: 반드시 true로 설정되어선 안 됩니다. 필요한 경우, 이 유형은 기능이 완료된 후 beta로 변경될 수 있습니다.
  • 최대 수명: 기본 브랜치에 병합된 후 4개월
  • 문서: 이 유형의 기능 플래그는 대부분 완료되지 않은 코드를 숨기고 있기 때문에 GitLab의 모든 기능 플래그 페이지에 문서화될 필요가 없습니다.
  • 롤아웃 이슈: wip 기능 플래그는 활성화되기 전에 다른 유형으로 전환되어야 하기 때문에 롤아웃 이슈가 필요할 가능성이 거의 없습니다.

사용법

# 기능 플래그가 활성화되었는지 확인
Feature.enabled?(:my_wip_flag, project)

# 기능 플래그가 비활성화되었는지 확인
Feature.disabled?(:my_wip_flag, project)

# Frontend로 기능 플래그 푸시
push_frontend_feature_flag(:my_wip_flag, project)

beta 유형

현재 형태로는 특정 사용 사례에 대해 feature를 확장, 지원 및 유지 관리할 수 있는 확신이 없을 수 있습니다(예시). 또한 feature가 충분히 완성되지 않아 MVC로 고려할 수 없는 시나리오도 있을 수 있습니다. 이러한 경우 플래그를 제공하면 엔지니어 및 고객이 해당 feature가 충분히 성능이 나아질 때까지 비활성화할 수 있습니다.

Constraints

  • default_enabled: 특정 온프레미스 설치에서 이유 있는 경우에만 확장성 문제로 인해 이 기능이 비활성화될 수 있도록 “릴리스”될 수 있게끔 true로 설정될 수 있습니다.
  • 최대 수명: 기본 브랜치에 병합된 후 6개월
  • 문서: 이 유형의 기능 플래그는 GitLab의 모든 기능 플래그 페이지에 반드시 문서화되어야 합니다.
  • 롤아웃 이슈: Feature flag Roll Out 템플릿에서 생성된 롤아웃 이슈가 반드시 있어야 합니다.

사용법

# 기능 플래그가 활성화되었는지 확인
Feature.enabled?(:my_beta_flag, project)

# 기능 플래그가 비활성화되었는지 확인
Feature.disabled?(:my_beta_flag, project)

# Frontend로 기능 플래그 푸시
push_frontend_feature_flag(:my_beta_flag, project)

ops 유형

ops 기능 플래그는 GitLab 제품 동작의 운영적 측면을 제어하는 장기간의 기능 플래그입니다. 예를 들어, Sidekiq Worker 동작과 같은 성능에 영향을 미칠 수 있는 기능을 비활성화하는 기능 플래그가 있습니다.

이 유형을 사용하는 것은 인스턴스/그룹/프로젝트/사용자 설정을 도입하지 않을 것이라는 의사 결정을 따라야 함을 기억하세요.

Constraints

  • default_enabled: 대부분의 경우에는 false로 설정되어야 하며, 일시적인 확장성 문제의 해결이나 프로덕션 문제를 디버깅하는 데 도움이 되어야만 활성화될 수 있습니다.
  • 최대 수명: 12개월
  • 문서: 이 유형의 기능 플래그는 GitLab의 모든 기능 플래그 페이지에 문서화되어야 함과 동시에 사용 시기를 설명하는 운영적 실행 문서와 관련되어야 합니다.
  • 롤아웃 이슈: 활성화 또는 비활성화되는 시기를 예측하기 어려우므로 롤아웃 이슈가 필요하지 않을 가능성이 매우 높습니다.

사용법

# 기능 플래그가 활성화되었는지 확인
Feature.enabled?(:my_ops_flag, project)

# 기능 플래그가 비활성화되었는지 확인
Feature.disabled?(:my_ops_flag, project)

# Frontend로 기능 플래그 푸시
push_frontend_feature_flag(:my_ops_flag, project)

experiment 유형

experiment 기능 플래그는 GitLab.com에서 A/B 테스트에 사용됩니다.

experiment 기능 플래그는 beta 기능 플래그와 동일한 표준을 준수해야 하지만 인터페이스에는 약간의 차이가 있습니다. 실험 기능 플래그에는 Experiment 추적 템플릿을 사용하여 생성된 롤아웃 이슈가 있어야 합니다. 더 많은 정보는 실험 가이드에서 확인할 수 있습니다.

제약 사항

  • default_enabled: true로 설정하면 절대 안 됩니다.
  • 최대 수명: 기본 브랜치로 병합된 후 6개월

worker 유형

worker 기능 플래그는 Sidekiq 작업 지연과 같은 Sidekiq 작업을 제어하는 특별한 ops 플래그입니다.

worker 기능 플래그는 워커 이름 자체를 사용하여 동적으로 생성될 수 있기 때문에 YAML 정의가 없는 것으로 보입니다. 예를 들어 run_sidekiq_jobs_AuthorizedProjectsWorker와 같이 워커 유형 기능 플래그를 사용하는 예는 Sidekiq 작업 지연에서 찾을 수 있습니다.

(사용되지 않음) development 유형

development 유형은 gitlab_com_derisk, wip, beta 기능 플래그 유형을 선호하여 사용되지 않습니다.

기능 플래그 정의 및 유효성 검사

개발(RAILS_ENV=development) 또는 테스트(RAILS_ENV=test) 중에는 모든 기능 플래그 사용이 엄격하게 유효성을 검사합니다.

이 프로세스는 코드베이스에서 일관된 기능 플래그 사용을 보장하기 위한 것입니다. 모든 기능 플래그는 반드시 다음을 준수해야 합니다:

  • 알려진 것. 명시적으로 정의된 기능 플래그만 사용하세요 (experiment, worker, undefined 유형의 기능 플래그 제외).
  • 두 번 정의되어서는 안 됩니다. FOSS 또는 EE 중 하나에서 정의되어야 하며 둘 다에서는 안 됩니다.
  • 정의 파일이 없는 기능 플래그의 경우 모든 호출에서 유효하고 일관된 type:을 사용하세요.
  • 소유자가 있어야 합니다.

GitLab에서 알려진 모든 기능 플래그는 다음의 YAML 파일에 자체 문서화되어 저장됩니다:

각 기능 플래그는 여러 필드로 구성된 별도의 YAML 파일에 정의됩니다:

필드 필요 여부 설명
name 기능 플래그의 이름
type 기능 플래그의 유형
default_enabled 기능 플래그의 기본 상태
introduced_by_url 기능 플래그를 도입한 병합 요청의 URL
milestone 기능 플래그가 생성된 마일스톤
group 기능 플래그를 소유하는 그룹
feature_issue_url 아니오 원본 기능 이슈의 URL
rollout_issue_url 아니오 기능 플래그 롤아웃을 다루는 이슈의 URL
log_state_changes 아니오 기능 플래그의 상태를 기록하는 데 사용

참고: RAILS_ENV=production에서 실행할 때 모든 유효성 검사가 건너뜁니다.

새 기능 플래그 생성

참고: GitLab 페이지는 다른 프로세스를 사용하여 기능 플래그를 사용합니다.

GitLab 코드베이스는 새로운 기능 플래그 정의를 생성하는 데 전용 도구인 bin/feature-flag를 제공합니다. 이 도구는 새 기능 플래그에 대해 여러 질문을 하고, 그런 다음 config/feature_flags 또는 ee/config/feature_flags에 YAML 정의를 생성합니다.

개발 또는 테스트 환경에서는 YAML 정의 파일이 있는 기능 플래그만 사용할 수 있습니다.

$ bin/feature-flag my_feature_flag
>> 기능 플래그 유형을 지정하세요
?> beta
유형 'beta'를 선택했습니다

>> 기능 플래그가 속하는 그룹 레이블을 선택하세요. 다음 목록에서 선택하세요:
1. group::group1
2. group::group2
?> 2
그룹 'group::group2'를 선택했습니다

>> 원본 기능 이슈의 URL(건너뛰려면 입력):
?> https://gitlab.com/gitlab-org/gitlab/-/issues/435435

>> 기능 플래그를 도입하는 MR의 URL(건너뛰고 MR에서 Danger가 직접 제안하도록 하려면 입력):
?> https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141023

>> 기능 플래그 DRI의 사용자 이름(건너뛰려면 입력):
?> bob

>> 이것이 EE 전용 기능입니까(건너뛰려면 입력):
?> [리턴]

>> 임시로 복사해 두었던 이슈 컨텐츠를 누르면, 임의의 키를 누르세요 🚀
?> [리턴하여 "새 이슈" 페이지가 열리고 컨텐츠를 붙여넣기만 하면 됩니다]

>> 롤아웃 이슈의 URL(건너뛰려면 입력):
?> https://gitlab.com/gitlab-org/gitlab/-/issues/437162

config/feature_flags/beta/my_feature_flag.yml 파일이 생성되었습니다
---
name: my_feature_flag
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/435435
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141023
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/437162
milestone: '16.9'
group: group::composition analysis
type: beta
default_enabled: false

새롭게 도입된 기능 플래그는 기본적으로 비활성화되어야 합니다.

기능이 기능 플래그 뒤에서 개발 및 병합되었을 경우 변경 내용이 포함되어서는 안 됩니다. 변경 내용은 기능 플래그를 제거하는 병합 요청이나 기능 플래그의 기본 값을 활성화로 설정하는 병합 요청 중 하나에 추가되어야 합니다. 기능에 데이터베이스 마이그레이션이 포함된 경우 데이터베이스 변경 사항에 대한 변경 로그 항목이 포함되어야 합니다.

참고: EE에서만 사용되는 기능 플래그를 만들려면 --ee 플래그를 추가하세요: bin/feature-flag --ee

새로운 플래그의 명명

새 기능 플래그의 이름을 선택할 때 다음 가이드라인을 고려하세요:

  • 짧지만 혼란스러운 것보다 길고 설명이 잘 된 이름이 좋습니다.
  • 이름은 스네이크 케이스로 작성하세요 (my_cool_feature_flag).
  • 부정을 피하기 위해 이름에 disable를 사용하지 않습니다(또는 문서화해야 함). hide_, remove_, 또는 disallow_로 시작하도록 이름을 지정하세요.

    소프트웨어 엔지니어링에서 이 문제는 “부울 변수에 대한 부정적인 이름”로 알려져 있습니다. 그러나 우리는 부정적인 단어를 완전히 금지할 순 없으므로 기능 플래그를 기본적으로 비활성화하도록 도입하거나 플래그 뒤로 기능을 이동하여 기능을 제거하거나 배우자별로 플래그를 선택적으로 비활성화할 수 있게 사용하세요.

깨진 마스터(main) 브랜치의 리스크

경고: 새로운 Feature flags을 도입하는 MR에서 반드시 사용되어야 합니다. 그렇게 하지 않으면 master 브랜치에서만 실행되는 rspec:feature-flags 작업으로 깨진 마스터 시나리오가 발생합니다.

옵션: .patch 파일 추가로 자동으로 feature flags 제거하기

gitlab-housekeeperDeleteOldFeatureFlags keep를 사용하여 feature flag 코드를 자동으로 삭제할 수 있습니다. 이 도구는 주기적으로 실행되어 코드에서 오래된 feature flags를 자동으로 정리합니다.

이 도구가 코드에서 feature flag 사용을 자동으로 삭제하려면 feature flag YAML 파일과 동일한 이름의 .patch 파일을 추가하면 됩니다. 파일명은 .yml 확장자 대신 .patch 확장자를 사용하여야 합니다.

예를 들어, 다음 단계로 config/feature_flags/beta/my_feature_flag.yml에 대한 패치 파일을 생성할 수 있습니다:

  1. feature flag my_feature_flag 사용을 제거하는 코드를 로컬에서 편집합니다. feature flag가 이미 활성화된 상태에서 변경 사항을 진행 중이라고 가정합니다.
  2. git diff > config/feature_flags/beta/my_feature_flag.patch 명령을 실행합니다.
  3. feature flag 사용을 제거한 파일의 변경 사항을 되돌립니다.
  4. 이 파일 config/feature_flags/beta/my_feature_flag.patch를 feature flag를 추가하는 브랜치에 커밋합니다.

이후에 gitlab-housekeeper는 이 패치를 적용하여 feature flag를 자동으로 정리합니다.

모든 feature flags 나열하기

환경의 모든 feature flags를 Slack에 출력하려면 ChatOps 사용하여 run feature list 명령을 사용하세요. 예를 들면:

/chatops run feature list --dev
/chatops run feature list --staging

Feature flag 토글하기

기능 flag 토글에 대한 자세한 정보는 변경 사항 배포를 참조하세요.

Feature flag 삭제하기

기능 flag 삭제에 대한 자세한 정보는 feature flags 정리를 참조하세요.

Feature flag를 사용하여 개발하기

GitLab 코드베이스에서 feature flags를 사용하는 주요 방법은 다음과 같습니다:

Backend

feature flag 인터페이스는 lib/feature.rb에 정의되어 있습니다. 이 인터페이스는 feature flag가 활성화되었는지 여부를 확인하기 위한 메서드 집합을 제공합니다:

if Feature.enabled?(:my_feature_flag, project)
  # feature flag가 활성화된 경우 코드를 실행합니다
else
  # feature flag가 비활성화된 경우 코드를 실행합니다
end

if Feature.disabled?(:my_feature_flag, project)
  # feature flag가 비활성화된 경우 코드를 실행합니다
end

구성되지 않은 feature flags의 기본 동작은 YAML 정의의 default_enabled:로 제어됩니다.

feature flag에 YAML 정의가 없는 경우 개발 또는 테스트 환경에서 오류가 발생하고, 프로덕션 환경에서는 false가 반환됩니다.

(실험, 워커 및 정의된) 유형에만 정의 파일이 없는 feature flags의 경우 Feature.enabled?Feature.disabled? 호출 시 type:를 전달해야 합니다:

if Feature.enabled?(:experiment_feature_flag, project, type: :experiment)
  # feature flag가 활성화된 경우 코드를 실행합니다
end

if Feature.disabled?(:worker_feature_flag, project, type: :worker)
  # feature flag가 비활성화된 경우 코드를 실행합니다
end

경고: 응용 프로그램 로드 시 feature flags를 사용하지 마십시오. 예를 들어, config/initializers/*에서 Feature 클래스를 사용하거나 클래스 레벨에서 사용하는 것은 예상치 못한 오류를 일으킬 수 있습니다. 이러한 오류는 feature flag 어댑터가 종속하는 데이터베이스가 로드 시점에 존재하지 않기 때문에 발생합니다(특히 새로 설치하는 경우). 호출자가 데이터베이스의 존재 여부를 확인하는 것은 권장되지 않습니다. 일부 어댑터는 데이터베이스를 전혀 필요로하지 않기 때문입니다(예: HTTP 어댑터). feature flag 설정 확인은 Feature 네임스페이스에 추상화되어야 합니다. 또한 이 방법은 feature flag 변경 시 애플리케이션을 다시로드해야 합니다. 따라서 프로덕션에서 SRE에게 Web/API/Sidekiq 플릿을 다시로드하도록 요청해야 합니다. 이로 인해 변경 사항이 완전히 전파/롤백하는 데 시간이 걸립니다. 이러한 이유로 환경 변수(예: ENV['YOUR_FEATURE_NAME']) 또는 gitlab.yml 대신 이러한 이유로 환경 변수(예: ENV['YOUR_FEATURE_NAME']) 또는 gitlab.yml을 사용해야 합니다.

다음은 피해야 할 패턴의 예시입니다:

class MyClass
  if Feature.enabled?(:...)
    new_process
  else
    legacy_process
  end
end

순환 감지

많은 feature flags가 있는 경우 어디에서 호출되었는지 항상 명확하지 않습니다. 한 feature flag의 평가가 다른 feature flag의 평가를 요구하는 순환을 피십시오. 이렇게 하면 순환이 발생할 경우 기본 값을 반환하게 되고 순환을 깨게 됩니다.

이 순환 감지가 올바르게 작동하려면 항상 Feature::enabled?을 통해 feature 값을 액세스하고 낮은 수준의 Feature::get 사용을 피해야 합니다. 이러한 경우가 발생하면 Feature::RecursionError 예외를 오류 추적기로 등록합니다.

Frontend

UI 요소에 feature flag를 사용할 때 백엔드 코드에 대한 feature flag도 항상 사용하십시오(만약 있다면). 이렇게 하면 feature가 활성화될 때까지 해당 기능을 사용할 수 없도록 보장할 수 있습니다.

ApplicationController에서 상속된 모든 컨트롤러에서 사용할 수 있는 push_frontend_feature_flag 메서드를 사용하세요. 예를 들면 다음과 같이 feature flag의 상태를 노출하는 데 이 메서드를 사용할 수 있습니다:

before_action do
  # 프로젝트 또는 사용자별로 범위를 지정하는 것이 좋습니다
  push_frontend_feature_flag(:vim_bindings, project)
end

def index
  # ...
end

def edit
  # ...
end

그런 다음 JavaScript에서 feature flag의 상태를 다음과 같이 확인할 수 있습니다:

if ( gon.features.vimBindings ) {
  // ...
}

JavaScript에서 feature flag의 이름은 항상 camelCase이므로 gon.features.vim_bindings를 확인하는 것은 작동하지 않을 것입니다.

experiment, workerundefined 유형에만 정의 파일이 없는 feature flags의 경우 push_frontend_feature_flag 호출 시 type:를 전달해야 합니다:

before_action do
  push_frontend_feature_flag(:vim_bindings, project, type: :experiment)

기능 사용자

특징 플래그에 액터를 사용하는 것이 강력히 권장됩니다. 액터는 특정 프로젝트, 그룹 또는 사용자에 대해서만 피처 플래그를 활성화하는 간단한 방법을 제공합니다. 이로써 로그 및 오류를 필터링하여 예를 들어 액터에 기반하여 디버깅을 수월하게 할 수 있습니다. 이렇게 함으로써 gitlab-org 또는 gitlab-com 그룹에서 먼저 피처를 활성화시킬 수 있으며, 다른 사용자들에게는 영향을 주지 않게 할 수도 있습니다.

액터는 특정 방식으로 기능을 전체적으로 배포하는 데도 쉽게 사용할 수 있습니다. 예를 들어 1%의 배포로 특정 액터에 대해 피처를 활성화한 경우, 해당 액터는 10%, 50%, 100%에서도 피처를 계속 활성화합니다.

GitLab은 다음과 같은 피처 플래그 액터를 지원합니다:

  • User 모델
  • Project 모델
  • Group 모델
  • 현재 요청

액터는 Feature.enabled? 호출의 두 번째 매개변수입니다. 예를 들어:

Feature.enabled?(:feature_flag, project)

FeatureGate를 포함하는 모델은 .actor_from_id 클래스 메서드가 있습니다. 모델의 ID를 가지고 있고 피처 플래그 상태를 확인할 때 모델을 필요로하지 않는 경우, 데이터베이스 쿼리를 만들지 않고도 .actor_from_id를 사용하여 피처 플래그 상태를 확인할 수 있습니다.

# 나쁨 -- 불필요한 쿼리가 실행됩니다
Feature.enabled?(:feature_flag, Project.find(project_id))

# 좋음 -- 프로젝트에 대한 쿼리가 없음
Feature.enabled?(:feature_flag, Project.actor_from_id(project_id))

# 좋음 -- 프로젝트 모델이 피처 플래그 확인 후 사용됨
project = Project.find(project_id)
return unless Feature.enabled?(:feature_flag, project)
project.update!(column: value)

자세한 내용은 ChatOps를 사용하여 피처 플래그를 활성화하거나 비활성화하려면 GitLab에서 제공하는 스테이징 및 프로덕션과 같은 환경에서 피처 플래그를 선택적으로 활성화 또는 비활성화하는 방법을 확인하세요.

플래그 상태는 하위 그룹 또는 프로젝트에서 상위 그룹으로 상속되지 않습니다. 전체 그룹 계층 구조에 대해 일관된 플래그 상태가 필요한 경우, 상위 수준 그룹을 액터로 사용을 고려하십시오. 이 그룹은 어떤 그룹이나 프로젝트에 #root_ancestor를 호출하여 찾을 수 있습니다.

Feature.enabled?(:feature_flag, group.root_ancestor)

액터 유형 혼합

일반적으로 특정 피처 플래그를 위한 Feature.enabled? 호출의 모든 액터 유형에서 동일한 유형의 액터만을 사용해야하며, 서로 다른 액터 유형을 혼합해서는 안됩니다.

액터 유형을 혼합하는 것은 버그를 발생시키는 방법으로 피처가 동일한 요청 내에서 다른 시점에서 활성화 또는 비활성화될 수 있습니다. 예를 들어, 컨트롤러 수준에서 플래그를 그룹 액터를 사용하여 확인하고 서비스 수준에서 사용자 액터를 확인하는 경우, 기능이 동일한 요청 내에서 다른 시점에서 활성화 및 비활성화 될 수 있습니다.

일부 상황에서 일관된 결과로 도달하기 위해 안전하게 액터 유형을 혼합할 수 있습니다. 예를 들어, 웹훅은 그룹 또는 프로젝트와 연관시킬 수 있으므로, 웹훅의 피처 플래그는 같은 피처 플래그를 사용하여 그룹 및 프로젝트 웹훅에 대해 기능을 롤아웃할 수 있습니다.

다른 액터 유형을 사용해야하고 혼합시키지 못하는 상황이면, 각 액터 유형에 대해 별도의 플래그를 사용해야합니다. 예를 들어:

Feature.enabled?(:feature_flag_group, group)
Feature.enabled?(:feature_flag_user, user)

인스턴스 액터

경고: 인스턴스 전체적인 피처 플래그는 기능이 전체 인스턴스에 연결될 때만 사용해야 합니다. 항상 다른 액터를 우선시 해야 합니다.

일부 경우에는 피처 플래그를 그룹이나 프로젝트를 기반으로 사용하기 어려운 경우가 있을 수 있습니다. 관리자 설정의 경우가 좋은 예입니다. 그룹이나 프로젝트를 기반으로 피처 플래그를 활성화하는 것은 불가능하기 때문입니다.

사용자 액터는 피처 플래그가 관리자가 아닌 사용자에게 활성화될 수 있지만 실제 관리자가 활성화되지 않을 수 있으므로 혼란스러울 수 있습니다.

대신 :instance 심볼을 Feature.enabled?의 두 번째 인자로 사용하여 GitLab 인스턴스로 사용할 수 있습니다.

Feature.enabled?(:feature_flag, :instance)

현재 요청 액터

호출마다 일관되지 않은 결과가 반환될 수 있으므로 시간의 퍼센트 롤아웃 사용을 권장하지 않습니다.

반면에 현재 요청을 액터로 사용하는 것이 권장됩니다.

# 나쁨
Feature.enable_percentage_of_time(:feature_flag, 40)
Feature.enabled?(:feature_flag)

# 좋음
Feature.enable_percentage_of_actors(:feature_flag, 40)
Feature.enabled?(:feature_flag, Feature.current_request)

현재 요청을 액터로 사용할 때, 요청의 문맥에서 동일한 값을 반환해야합니다. 현재 요청 액터는 SafeRequestStore를 사용하여 구현되었으므로 일관된 피처 플래그 값을 가져야 합니다:

  • 랙 요청
  • Sidekiq 워커 실행
  • ActionCable 워커 실행

기존의 피처를 시간의 퍼센트에서 현재 요청 액터로 마이그레이션하려면 새로운 피처 플래그를 생성하는 것이 좋습니다. 기존의 percentage_of_time 값, 코드 변경의 배포, percentage_of_actors로 전환하는 타이밍을 제어하는 것이 어려우므로 새로운 피처 플래그를 생성하는 것이 좋습니다.

프로덕션에서 확인하기 위해 액터 사용

경고: 테스트 환경으로써 프로덕션을 사용하는 것은 권장되지 않습니다. 프로덕션에 대한 테스트 환경을 위해 우리의 테스트 환경을 사용하세요.

스테이징 환경은 프로덕션과 유사한 환경에서 기능을 테스트할 수 있는 방법을 제공하지만, 프로덕션 환경에 특정 프로덕션 환경에만 특정한 성능 지표를 비교할 수 있는 방법을 제공하지 않습니다. 개발 중인 피처 플래그가 활성화된 상태에서 프로덕션 프로젝트를 가지고 있으면, Sitespeed 보고서와 같은 도구를 사용하여 새 코드의 메트릭을 확인할 수 있습니다.

이 접근 방법은 이미 Sitespeed에서 이전 코드베이스를 추적하고 있으면 더욱 유용하며, 피처 플래그 롤아웃 전후의 성능을 정확하게 비교할 수 있습니다.

추가 객체를 액터로 활성화하기

액터에 기반한 피처 게이트를 사용하려면 해당 모델은 flipper_id에 응답해야합니다. 예를 들어, Foo 모델을 사용하여 활성화하려면:

class Foo < ActiveRecord::Base
  include FeatureGate
end

FeatureGate를 포함하거나 flipper_id 메서드를 노출하는 모델 만이 Feature.enabled?에 대한 액터로 사용될 수 있습니다.

라이선스 기능을 위한 기능 플래그

라이선스 기능 이름과 동일한 이름의 기능 플래그는 사용할 수 없습니다. 그렇게 하면 이름 충돌이 발생하기 때문입니다. 이는 혼란을 초래하므로 널리 논의되었으며 제거되었습니다.

라이선스 기능을 확인하려면 lib/feature.rb에 전용 기능 플래그를 추가하고 명시적으로 확인해야 합니다. 예를 들어:

Feature.enabled?(:licensed_feature_feature_flag, project) &&
  project.feature_available?(:licensed_feature)

기능 그룹

기능 그룹은 반드시 lib/feature.rb.register_feature_groups 메서드에 정적으로 정의되어야 하지만, 구현은 동적일 수 있습니다(예: DB 쿼리).

lib/feature.rb에서 정의한 후, 특정 기능 그룹에 대해 기능을 활성화할 수 있습니다. 이를 위해 features API의 feature_group 매개변수를 사용하세요.

사용 가능한 기능 그룹은 다음과 같습니다:

그룹 이름 스코프 지정 설명
gitlab_team_members 사용자 gitlab-com의 구성원에 대해 기능을 활성화합니다.

기능 그룹은 그룹 이름을 통해 활성화할 수 있습니다:

Feature.enable(:feature_flag_name, :gitlab_team_members)

로컬에서 기능 플래그 제어

레일즈 콘솔에서

레일즈 콘솔(rails c)에서 기능 플래그를 활성화하려면 다음 명령을 입력하세요:

Feature.enable(:feature_flag_name)

마찬가지로 다음 명령은 기능 플래그를 비활성화합니다:

Feature.disable(:feature_flag_name)

특정 Gate에 대해 기능 플래그를 활성화할 수도 있습니다:

Feature.enable(:feature_flag_name, Project.find_by_full_path("root/my-project"))

레일즈 콘솔에서 기능 플래그를 수동으로 활성화하거나 비활성화하면 해당 플래그의 기본 값을 덮어쓸 수 있습니다. 이는 플래그의 default_enabled 속성을 변경할 때 혼란을 줄 수 있습니다.

기능 플래그를 기본 상태로 재설정하려면:

Feature.remove(:feature_flag_name)

브라우저에서

로컬로 기능 플래그를 관리하려면 http://gdk.test:3000/rails/features에 액세스하세요.

로깅

기능 플래그의 사용 및 상태는 다음 중 하나에 해당되는 경우 로깅됩니다:

  • 기능 플래그 정의에서 log_state_changestrue로 설정되어 있는 경우.
  • 마일스톤이 현재 GitLab 버전보다 크거나 같은 마일스톤을 참조하는 경우.

기능 플래그의 상태가 로깅된 경우, Kibana에서 "json.feature_flag_states": "feature_flag_name:1" 또는 "json.feature_flag_states": "feature_flag_name:0" 조건을 사용하여 식별할 수 있습니다. 여기에서 예제를 확인할 수 있습니다.

참고: 요청 중 20%만 기능 플래그의 상태가 로깅됩니다. 이는 feature_flag_state_logs 기능 플래그에 의해 제어됩니다.

변경 로그

기능이 최종 사용자에 의해 직접(예: 기능 사용 가능 여부) 또는간접적으로(예: 배경 작업, 성능 개선 또는 데이터베이스 마이그레이션 업데이트의 이점을 활용할 수 있는 능력) 접근할 수 없는 경우 변경 로그를 도입하는 것을 피하려고 합니다.

  • 데이터베이스 마이그레이션은 자체 관리형 고객이 업그레이드하기 전에 데이터베이스 변경 사항을 인식해야 하기 때문에 간접적으로 최종 사용자가 접근할 수 있습니다. 이러한 이유로 데이터베이스 마이그레이션에는 변경 로그 항목이 있어야 합니다.
  • 기본적으로 꺼져 있는 기능 플래그 뒤의 변경 사항은 변경 로그 항목에 포함되어서는 안 됩니다.
  • 기본적으로 켜져 있는 기능 플래그 뒤의 변경 사항은 변경 로그 항목에 포함되어야 합니다.
  • 기능 플래그 자체를 변경(플래그 제거, 기본 켜기 설정)하는 경우에는 변경 로그 항목이 있어야 합니다. 변경 로그 항목 유형을 결정하기 위해 플로차트를 사용하세요.

    flowchart LR FDOFF(현재 플래그가<br>'기본: 끔') FDON(현재 플래그가<br>'기본: 켬') CDO{기본값으로<br>'켬' 변경} ACF(추가됨/변경됨/수정됨/기타...) RF{플래그 제거} RF2{플래그 제거} RC(제거됨/변경됨) OTHER(기타) FDOFF -->CDO-->ACF FDOFF -->RF RF-->|새 코드 유지?| ACF RF-->|기존 코드 유지?| OTHER FDON -->RF2 RF2-->|기존 코드 유지?| RC RF2-->|새 코드 유지?| OTHER
  • 기능 플래그에 대한 변경 로그는 특정 플래그가 아닌 기능에 대해 설명해야 합니다(위의 플로차트에서 기타).
  • 기능 플래그는 버그 수정 또는 유지 관리 작업을 롤아웃하는 데 사용할 수도 있습니다. 이 경우 변경 로그는 이와 관련되어야 합니다. 예를 들어, 수정됨이나 기타.

테스트에서의 기능 플래그

코드베이스에 기능 플래그를 도입하면 테스트되어야 하는 추가 코드 경로가 생성됩니다. 기능 플래그에 영향을 받는 모든 코드에 대한 자동화된 테스트를 활성화되어 있는 상태와 비활성화되어 있는 상태 모두 포함하는 것이 강력히 권장됩니다. 자동화된 테스트가 두 상태에 대해 포함되어 있지 않으면, 실행될 때 생기는 기능과 관련된 기능에 대한 기능을 수동으로 테스트해야 합니다.

테스트 환경을 사용할 때 모든 기능 플래그가 기본적으로 활성화됩니다. 플래그는 spec/spec_helper.rb 파일에서 기본적으로 비활성화될 수 있습니다. 가능한 경우 이유를 설명하는 주석을 추가하세요. 가능한 경우 참조용 이슈 URL을 첨부할 수도 있습니다.

경고: 이는 기본적으로 기능 플래그를 활성화하지 않는 끝간 테스트에는 적용되지 않습니다. 끝간 테스트에서 기능 플래그를 사용하는 데 대한 다른 절차가 있습니다.

테스트에서 기능 플래그를 비활성화하려면 stub_feature_flags 도우미를 사용하세요. 예를 들어, 테스트에서 ci_live_trace 기능 플래그를 전역적으로 비활성화하려면:

stub_feature_flags(ci_live_trace: false)

Feature.enabled?(:ci_live_trace) # => false

두 개의 경로에 대해 테스트하는 일반적인 패턴은 다음과 같습니다:

it 'ci_live_trace 작동 확인' do
  # 테스트는 기본적으로 활성화되어 있다고 가정합니다.
  Feature.enabled?(:ci_live_trace) # => true
end

context 'ci_live_trace가 비활성화된 경우' do
  before do
    stub_feature_flags(ci_live_trace: false)
  end

  it 'ci_live_trace가 작동하지 않음' do
    Feature.enabled?(:ci_live_trace) # => false
  end
end

특정 사용자에게만 기능 플래그를 활성화하거나 사용하지 않게 하려면 도우미에 전달되는 옵션에 이를 지정할 수 있습니다. 예를 들어, 특정 프로젝트에 대해 ci_live_trace 기능 플래그를 활성화하려면:

project1, project2 = build_list(:project, 2)

# 프로젝트1에서만 기능이 활성화됩니다.
stub_feature_flags(ci_live_trace: project1)

Feature.enabled?(:ci_live_trace) # => false
Feature.enabled?(:ci_live_trace, project1) # => true
Feature.enabled?(:ci_live_trace, project2) # => false

FlipperGate의 동작은 다음과 같습니다:

  1. 지정된 사용자에게 오버라이드를 활성화할 수 있습니다.
  2. 지정된 사용자의 오버라이드를 비활성화하여 기본 상태로 돌아갈 수 있습니다.
  3. 명시적으로 지정된 사용자를 비활성화한 경우를 모델링할 수 있는 방법이 없습니다.
Feature.enable(:my_feature)
Feature.disable(:my_feature, project1)
Feature.enabled?(:my_feature) # => true
Feature.enabled?(:my_feature, project1) # => true

Feature.disable(:my_feature2)
Feature.enable(:my_feature2, project1)
Feature.enabled?(:my_feature2) # => false
Feature.enabled?(:my_feature2, project1) # => true

have_pushed_frontend_feature_flags

push_frontend_feature_flag에 기능 플래그를 HTML에 추가했는지를 테스트하기 위해 have_pushed_frontend_feature_flags를 사용합니다.

예를들어,

stub_feature_flags(value_stream_analytics_path_navigation: false)

visit group_analytics_cycle_analytics_path(group)

expect(page).to have_pushed_frontend_feature_flags(valueStreamAnalyticsPathNavigation: false)

stub_feature_flags vs Feature.enable*

테스트 환경에서 기능 플래그를 활성화하는 데 stub_feature_flags를 사용하는 것이 좋습니다. 이 방법은 간단하고 잘 설명된 인터페이스를 제공하여 간단한 사용 사례를 처리합니다.

그러나 퍼센트롤아웃과 같은 더 복잡한 동작을 테스트해야 하는 경우도 있습니다. 이때 .enable_percentage_of_time 또는 .enable_percentage_of_actors를 사용할 수 있습니다.

# Good: 기능이 명시적으로 비활성화되어야 하는 경우, 정의되지 않은 경우 기본적으로 활성화됩니다
stub_feature_flags(my_feature: false)
stub_feature_flags(my_feature: true)
stub_feature_flags(my_feature: project)
stub_feature_flags(my_feature: [project, project2])

# Bad
Feature.enable(:my_feature_2)

# Good: my_feature를 시간의 50% 동안 활성화
Feature.enable_percentage_of_time(:my_feature_3, 50)

# Good: my_feature를 액터/게이트/물체의 50%에 대해 활성화
Feature.enable_percentage_of_actors(:my_feature_4, 50)

각 정의된 상태를 가진 기능 플래그는 테스트 실행 시에 유지됩니다:

Feature.persisted_names.include?('my_feature') => true
Feature.persisted_names.include?('my_feature_2') => true
Feature.persisted_names.include?('my_feature_3') => true
Feature.persisted_names.include?('my_feature_4') => true

Actor를 Stubbing하기

특정 Actor에 대해 기능 플래그를 활성화하려면 해당 표현을 Stub할 수 있습니다. Feature.enabled?Feature.disabled?에 전달되는 게이트는 FeatureGate를 포함하는 객체여야 합니다.

스펙에서는 사용자 정의 Actor를 빠르게 만들 수 있는 stub_feature_flag_gate 메서드를 사용할 수 있습니다:

gate = stub_feature_flag_gate('CustomActor')

stub_feature_flags(ci_live_trace: gate)

Feature.enabled?(:ci_live_trace) # => false
Feature.enabled?(:ci_live_trace, gate) # => true

테스트에서 기능 플래그 엔진 제어

테스트 환경에서의 Flipper 엔진은 메모리 모드 Flipper::Adapters::Memory에서 작동합니다. productiondevelopment 모드는 Flipper::Adapters::ActiveRecord를 사용합니다.

Flipper::Adapters::Memory 또는 ActiveRecord 모드를 사용하는지를 제어할 수 있습니다.

stub_feature_flags: true (기본 및 선호)

이 모드에서 Flipper는 Flipper::Adapters::Memory를 사용하도록 구성되며 모든 기능 플래그를 기본적으로 활성화하고 첫 사용 시 유지합니다.

기능 플래그 아래의 동작이 특정하지 않은 상황에서 테스트되지 않도록 주의하십시오.

stub_feature_flags: false

이는 메모리 스텁이 제거되고 Flipper::Adapters::ActiveRecord를 사용하며, 이 모드는 productiondevelopment에서 사용됩니다.

이 모드는 ActiveRecord와의 상호 작용을 테스트하려는 경우에만 사용해야 합니다.

종단간(검증) 테스트

종단간(검증) 테스트에서의 기능 플래그 토글은 다르게 작동합니다. 종단간 테스트 프레임워크는 Flipper를 직접 사용할 수 없기 때문에 공개 API를 사용합니다. 각 종단간 테스트는 테스트 중에 기능 플래그를 활성화 또는 비활성화할 수 있습니다. 또는 GitLab 리포지토리의 qa 디렉터리에서 하나 이상의 테스트를 실행할 때, 또는 GitLab QA를 통해 테스트를 실행할 때 테스트 전에 기능 플래그를 활성화하거나 비활성화할 수 있습니다.

위에서 언급했듯이, 종단간 테스트에서 기본적으로 기능 플래그가 활성화되지 않습니다. 종단간 테스트는 기능 플래그가 소스 코드에서 구현된 기본 상태로 실행되거나, 테스트가 기능 플래그를 명시적으로 활성화/비활성화하지 않는 한 GitLab 인스턴스의 기능 플래그의 현재 상태로 실행됩니다.

기능 플래그가 스테이징 또는 GitLab.com에서 변경될 경우, Slack 메시지가 #e2e-run-staging 또는 #e2e-run-production 채널에 게시되어 파이프라인 담당자가 해당 실패가 기능 플래그 변경 관련되어 있는지 더 쉽게 결정할 수 있도록 도와줍니다. 그러나 변경 사항을 작업 중인 경우, 종단간 테스트를 기능 플래그가 활성화된 상태에서 통과했음을 확인하여 예상치 않은 실패를 방지할 수 있습니다.

기능 플래그로 Sidekiq 워커 동작 제어

worker 타입의 기능 플래그는 Sidekiq 워커의 동작을 제어하는 데 사용할 수 있습니다.

Sidekiq 작업 연기

비활성화된 상태일 때, run_sidekiq_jobs_{WorkerName} 형식의 기능 플래그는 작업을 나중 시간에 스케줄링하여 워커의 실행을 지연시킵니다. 이 기능 플래그는 모든 워커에 대해 기본적으로 활성화됩니다. 작업을 연기하는 것은 워커 인스턴스가 인프라 리소스(예: 데이터베이스 및 데이터베이스 연결 풀)를 포화시키는 침투적 동작이 발생하는 사고 시 유용할 수 있습니다. 구현은 SkipJobs Sidekiq 서버 미들웨어에서 찾을 수 있습니다.

참고: 기능 플래그가 비활성화된 경우 작업은 무기한 연기됩니다. 워커가 안전하게 처리될 수 있다고 판단되면 기능 플래그를 제거하는 것이 중요합니다.

false로 설정하면 모든 작업이 무기한 연기됩니다. 처리를 다시 시작하려면 시간 비율 롤아웃을 사용할 수 있습니다. 예를들어:

# 어떠한 작업도 실행되지 않고, 모든 작업을 미룸
/chatops run feature set run_sidekiq_jobs_SlowRunningWorker false

# 작업의 10%만 실행하고, 90%를 미룸
/chatops run feature set run_sidekiq_jobs_SlowRunningWorker 10

# 작업의 50%만 실행하고, 50%를 미룸
/chatops run feature set run_sidekiq_jobs_SlowRunningWorker 50

# 모든 작업을 정상적으로 다시 실행
/chatops run feature delete run_sidekiq_jobs_SlowRunningWorker

Sidekiq 작업 삭제

작업을 연기하는 대신에, 기능 플래그 drop_sidekiq_jobs_{WorkerName}를 활성화하여 작업을 완전히 삭제할 수 있습니다. 이 기능 플래그는 작업이 안전하게 삭제될 수 있는 경우에 사용하십시오, 즉 미래에 처리할 필요가 없는 작업인 경우입니다.

# 모든 작업 삭제
/chatops run feature set drop_sidekiq_jobs_SlowRunningWorker true

# 정상적으로 작업 처리
/chatops run feature delete drop_sidekiq_jobs_SlowRunningWorker

참고: 작업 삭제 기능 플래그 (drop_sidekiq_jobs_{WorkerName})는 작업 연기 기능 플래그 (run_sidekiq_jobs_{WorkerName})보다 우선합니다. 즉, drop_sidekiq_jobs가 활성화되어 있고 run_sidekiq_jobs가 비활성화되어 있는 경우, 작업이 완전히 삭제됩니다.