summaryrefslogtreecommitdiff
path: root/doc/development/geo/framework.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/development/geo/framework.md')
-rw-r--r--doc/development/geo/framework.md158
1 files changed, 107 insertions, 51 deletions
diff --git a/doc/development/geo/framework.md b/doc/development/geo/framework.md
index 85fecc41cfb..de4d6fb869d 100644
--- a/doc/development/geo/framework.md
+++ b/doc/development/geo/framework.md
@@ -1,11 +1,13 @@
# Geo self-service framework (alpha)
-NOTE: **Note:** This document might be subjected to change. It's a
+NOTE: **Note:**
+This document might be subjected to change. It's a
proposal we're working on and once the implementation is complete this
documentation will be updated. Follow progress in the
[epic](https://gitlab.com/groups/gitlab-org/-/epics/2161).
-NOTE: **Note:** The Geo self-service framework is currently in
+NOTE: **Note:**
+The Geo self-service framework is currently in
alpha. If you need to replicate a new data type, reach out to the Geo
team to discuss the options. You can contact them in `#g_geo` on Slack
or mention `@geo-team` in the issue or merge request.
@@ -178,13 +180,17 @@ For example, to add support for files referenced by a `Widget` model with a
mount_uploader :file, WidgetUploader
+ def self.replicables_for_geo_node
+ # Should be implemented. The idea of the method is to restrict
+ # the set of synced items depending on synchronization settings
+ end
...
end
```
1. Create `ee/app/replicators/geo/widget_replicator.rb`. Implement the
`#carrierwave_uploader` method which should return a `CarrierWave::Uploader`.
- And implement the private `#model` method to return the `Widget` class.
+ And implement the class method `.model` to return the `Widget` class.
```ruby
# frozen_string_literal: true
@@ -193,14 +199,12 @@ For example, to add support for files referenced by a `Widget` model with a
class WidgetReplicator < Gitlab::Geo::Replicator
include ::Geo::BlobReplicatorStrategy
- def carrierwave_uploader
- model_record.file
+ def self.model
+ ::Widget
end
- private
-
- def model
- ::Widget
+ def carrierwave_uploader
+ model_record.file
end
end
end
@@ -215,7 +219,7 @@ For example, to add support for files referenced by a `Widget` model with a
require 'spec_helper'
- describe Geo::WidgetReplicator do
+ RSpec.describe Geo::WidgetReplicator do
let(:model_record) { build(:widget) }
it_behaves_like 'a blob replicator'
@@ -231,20 +235,32 @@ For example, to add support for files referenced by a `Widget` model with a
class CreateWidgetRegistry < ActiveRecord::Migration[6.0]
DOWNTIME = false
- def change
- create_table :widget_registry, id: :serial, force: :cascade do |t|
- t.integer :widget_id, null: false
- t.integer :state, default: 0, null: false
- t.integer :retry_count, default: 0
- t.string :last_sync_failure, limit: 255
- t.datetime_with_timezone :retry_at
- t.datetime_with_timezone :last_synced_at
- t.datetime_with_timezone :created_at, null: false
-
- t.index :widget_id, name: :index_widget_registry_on_repository_id, using: :btree
- t.index :retry_at, name: :index_widget_registry_on_retry_at, using: :btree
- t.index :state, name: :index_widget_registry_on_state, using: :btree
+ disable_ddl_transaction!
+
+ def up
+ unless table_exists?(:widget_registry)
+ ActiveRecord::Base.transaction do
+ create_table :widget_registry, id: :bigserial, force: :cascade do |t|
+ t.integer :widget_id, null: false
+ t.integer :state, default: 0, null: false, limit: 2
+ t.integer :retry_count, default: 0, limit: 2
+ t.text :last_sync_failure
+ t.datetime_with_timezone :retry_at
+ t.datetime_with_timezone :last_synced_at
+ t.datetime_with_timezone :created_at, null: false
+
+ t.index :widget_id
+ t.index :retry_at
+ t.index :state
+ end
+ end
end
+
+ add_text_limit :widget_registry, :last_sync_failure, 255
+ end
+
+ def down
+ drop_table :widget_registry
end
end
```
@@ -255,21 +271,28 @@ For example, to add support for files referenced by a `Widget` model with a
# frozen_string_literal: true
class Geo::WidgetRegistry < Geo::BaseRegistry
- include Geo::StateMachineRegistry
+ include Geo::ReplicableRegistry
+ MODEL_CLASS = ::Widget
MODEL_FOREIGN_KEY = :widget_id
belongs_to :widget, class_name: 'Widget'
end
```
+ The method `has_create_events?` should return `true` in most of the cases.
+ However, if the entity you add doesn't have the create event, don't add the
+ method at all.
+
+1. Update `REGISTRY_CLASSES` in `ee/app/workers/geo/secondary/registry_consistency_worker.rb`.
+
1. Create `ee/spec/factories/geo/widget_registry.rb`:
```ruby
# frozen_string_literal: true
FactoryBot.define do
- factory :widget_registry, class: 'Geo::WidgetRegistry' do
+ factory :geo_widget_registry, class: 'Geo::WidgetRegistry' do
widget
state { Geo::WidgetRegistry.state_value(:pending) }
@@ -301,14 +324,18 @@ For example, to add support for files referenced by a `Widget` model with a
require 'spec_helper'
- describe Geo::WidgetRegistry, :geo, type: :model do
- let_it_be(:registry) { create(:widget_registry) }
+ RSpec.describe Geo::WidgetRegistry, :geo, type: :model do
+ let_it_be(:registry) { create(:geo_widget_registry) }
specify 'factory is valid' do
expect(registry).to be_valid
end
include_examples 'a Geo framework registry'
+
+ describe '.find_registry_differences' do
+ ... # To be implemented
+ end
end
```
@@ -360,36 +387,58 @@ Widgets should now be replicated by Geo!
end
```
-1. Add fields `widget_count`, `widget_checksummed_count`, `widget_checksum_failed_count`,
- `widget_synced_count` and `widget_failed_count`
- to `GeoNodeStatus#RESOURCE_STATUS_FIELDS` array in `ee/app/models/geo_node_status.rb`.
+To do: Add verification on secondaries. This should be done as part of
+[Geo: Self Service Framework - First Implementation for Package File verification](https://gitlab.com/groups/gitlab-org/-/epics/1817)
+
+Widgets should now be verified by Geo!
+
+#### Metrics
+
+Metrics are gathered by `Geo::MetricsUpdateWorker`, persisted in
+`GeoNodeStatus` for display in the UI, and sent to Prometheus.
+
+1. Add fields `widget_count`, `widget_checksummed_count`,
+ `widget_checksum_failed_count`, `widget_synced_count`,
+ `widget_failed_count`, and `widget_registry_count` to
+ `GeoNodeStatus#RESOURCE_STATUS_FIELDS` array in
+ `ee/app/models/geo_node_status.rb`.
1. Add the same fields to `GeoNodeStatus#PROMETHEUS_METRICS` hash in
`ee/app/models/geo_node_status.rb`.
1. Add the same fields to `Sidekiq metrics` table in
`doc/administration/monitoring/prometheus/gitlab_metrics.md`.
-1. Add the same fields to `GET /geo_nodes/status` example response in `doc/api/geo_nodes.md`.
-1. Modify `GeoNodeStatus#load_verification_data` to make sure the fields mantioned above
- are set:
+1. Add the same fields to `GET /geo_nodes/status` example response in
+ `doc/api/geo_nodes.md`.
+1. Add the same fields to `ee/spec/models/geo_node_status_spec.rb` and
+ `ee/spec/factories/geo_node_statuses.rb`.
+1. Set `widget_count` in `GeoNodeStatus#load_data_from_current_node`:
+
+ ```ruby
+ self.widget_count = Geo::WidgetReplicator.primary_total_count
+ ```
+
+1. Add `GeoNodeStatus#load_widgets_data` to set `widget_synced_count`,
+ `widget_failed_count`, and `widget_registry_count`:
```ruby
- self.widget_count = Geo::WidgetReplicator.model.count
- self.widget_checksummed_count = Geo::WidgetReplicator.checksummed.count
- self.widget_checksum_failed_count = Geo::WidgetReplicator.checksum_failed.count
+ def load_widget_data
self.widget_synced_count = Geo::WidgetReplicator.synced_count
self.widget_failed_count = Geo::WidgetReplicator.failed_count
+ self.widget_registry_count = Geo::WidgetReplicator.registry_count
+ end
```
-1. Make sure `Widget` model has `checksummed` and `checksum_failed` scopes.
-1. Update `ee/spec/fixtures/api/schemas/public_api/v4/geo_node_status.json` with new fields.
-1. Update `GeoNodeStatus#PROMETHEUS_METRICS` hash in `ee/app/models/geo_node_status.rb` with new fields.
-1. Update `Sidekiq metrics` table in `doc/administration/monitoring/prometheus/gitlab_metrics.md` with new fields.
-1. Update `GET /geo_nodes/status` example response in `doc/api/geo_nodes.md` with new fields.
-1. Update `ee/spec/models/geo_node_status_spec.rb` and `ee/spec/factories/geo_node_statuses.rb` with new fields.
+1. Call `GeoNodeStatus#load_widgets_data` in
+ `GeoNodeStatus#load_secondary_data`.
-To do: Add verification on secondaries. This should be done as part of
-[Geo: Self Service Framework - First Implementation for Package File verification](https://gitlab.com/groups/gitlab-org/-/epics/1817)
+1. Set `widget_checksummed_count` and `widget_checksum_failed_count` in
+ `GeoNodeStatus#load_verification_data`:
-Widgets should now be verified by Geo!
+ ```ruby
+ self.widget_checksummed_count = Geo::WidgetReplicator.checksummed_count self.widget_checksum_failed_count = Geo::WidgetReplicator.checksum_failed_count
+ ```
+
+Widget replication and verification metrics should now be available in the API,
+the Admin Area UI, and Prometheus!
#### GraphQL API
@@ -428,8 +477,8 @@ Widgets should now be verified by Geo!
require 'spec_helper'
- describe Resolvers::Geo::WidgetRegistriesResolver do
- it_behaves_like 'a Geo registries resolver', :widget_registry
+ RSpec.describe Resolvers::Geo::WidgetRegistriesResolver do
+ it_behaves_like 'a Geo registries resolver', :geo_widget_registry
end
```
@@ -452,8 +501,8 @@ Widgets should now be verified by Geo!
require 'spec_helper'
- describe Geo::WidgetRegistryFinder do
- it_behaves_like 'a framework registry finder', :widget_registry
+ RSpec.describe Geo::WidgetRegistryFinder do
+ it_behaves_like 'a framework registry finder', :geo_widget_registry
end
```
@@ -484,7 +533,7 @@ Widgets should now be verified by Geo!
require 'spec_helper'
- describe GitlabSchema.types['WidgetRegistry'] do
+ RSpec.describe GitlabSchema.types['WidgetRegistry'] do
it_behaves_like 'a Geo registry type'
it 'has the expected fields (other than those included in RegistryType)' do
@@ -503,7 +552,7 @@ Widgets should now be verified by Geo!
it_behaves_like 'gets registries for', {
field_name: 'widgetRegistries',
registry_class_name: 'WidgetRegistry',
- registry_factory: :widget_registry,
+ registry_factory: :geo_widget_registry,
registry_foreign_key_field_name: 'widgetId'
}
```
@@ -511,6 +560,13 @@ Widgets should now be verified by Geo!
Individual widget synchronization and verification data should now be available
via the GraphQL API!
+1. Take care of replicating "update" events. Geo Framework does not currently support
+ replicating "update" events because all entities added to the framework, by this time,
+ are immutable. If this is the case
+ for the entity you're going to add, please follow <https://gitlab.com/gitlab-org/gitlab/-/issues/118743>
+ and <https://gitlab.com/gitlab-org/gitlab/-/issues/118745> as examples to add the new event type.
+ Please also remove this notice when you've added it.
+
#### Admin UI
To do: This should be done as part of