Commit cc492f2e authored by Mike Kozono's avatar Mike Kozono

Add Geo::PackageFileRegistry model

and its table.
parent 8b7bc6dd
......@@ -19,6 +19,7 @@ ActiveSupport::Inflector.inflections do |inflect|
group_view
job_artifact_registry
lfs_object_registry
package_file_registry
project_auto_devops
project_registry
project_statistics
......
# frozen_string_literal: true
class Geo::PackageFileRegistry < Geo::BaseRegistry
include ::Delay
STATE_VALUES = {
pending: 0,
started: 1,
synced: 2,
failed: 3
}.freeze
belongs_to :package_file, class_name: 'Packages::PackageFile'
scope :package_file_id_not_in, -> (ids) { where.not(package_file_id: ids) }
scope :never, -> { where(last_synced_at: nil) }
scope :failed, -> { with_state(:failed) }
scope :synced, -> { with_state(:synced) }
scope :retry_due, -> { where(arel_table[:retry_at].eq(nil).or(arel_table[:retry_at].lt(Time.now))) }
state_machine :state, initial: :pending do
state :pending, value: STATE_VALUES[:pending]
state :started, value: STATE_VALUES[:started]
state :synced, value: STATE_VALUES[:synced]
state :failed, value: STATE_VALUES[:failed]
before_transition any => :started do |registry, _|
registry.last_synced_at = Time.now
end
before_transition any => :pending do |registry, _|
registry.retry_at = 0
registry.retry_count = 0
end
before_transition any => :failed do |registry, _|
registry.retry_count += 1
registry.retry_at = registry.next_retry_time(registry.retry_count)
end
before_transition any => :synced do |registry, _|
registry.retry_count = 0
registry.last_sync_failure = nil
registry.retry_at = nil
end
event :start do
transition [:pending, :synced, :failed] => :started
end
event :synced do
transition [:started] => :synced
end
event :failed do
transition [:started] => :failed
end
event :resync do
transition [:synced, :failed] => :pending
end
end
# @return [Geo::PackageFileRegistry] an instance of this class
def self.for_model_record_id(id)
find_or_initialize_by(package_file_id: id)
end
def self.state_value(state_string)
STATE_VALUES[state_string]
end
# Override state machine failed! event method to record a failure message at
# the same time.
#
# @param [String] message error information
# @param [StandardError] error exception
def failed!(message, error = nil)
self.last_sync_failure = message
self.last_sync_failure += ": #{error.message}" if error.respond_to?(:message)
super()
end
end
# frozen_string_literal: true
class CreatePackageFileRegistry < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
create_table :package_file_registry, id: :serial, force: :cascade do |t|
t.integer :package_file_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 :package_file_id, name: :index_package_file_registry_on_repository_id, using: :btree
t.index :retry_at, name: :index_package_file_registry_on_retry_at, using: :btree
t.index :state, name: :index_package_file_registry_on_state, using: :btree
end
end
end
......@@ -2,15 +2,15 @@
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
# This file is the source Rails uses to define your schema when running `rails
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_10_25_194337) do
ActiveRecord::Schema.define(version: 2020_01_21_194300) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -91,6 +91,19 @@ ActiveRecord::Schema.define(version: 2019_10_25_194337) do
t.index ["success"], name: "index_lfs_object_registry_on_success"
end
create_table "package_file_registry", id: :serial, force: :cascade do |t|
t.integer "package_file_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 ["package_file_id"], name: "index_package_file_registry_on_repository_id"
t.index ["retry_at"], name: "index_package_file_registry_on_retry_at"
t.index ["state"], name: "index_package_file_registry_on_state"
end
create_table "project_registry", id: :serial, force: :cascade do |t|
t.integer "project_id", null: false
t.datetime "last_repository_synced_at"
......
# frozen_string_literal: true
FactoryBot.define do
factory :package_file_registry, class: 'Geo::PackageFileRegistry' do
association :package_file, factory: [:package_file, :npm]
last_sync_failure { nil }
last_synced_at { nil }
state { Geo::PackageFileRegistry.state_value(:pending) }
trait :synced do
state { Geo::PackageFileRegistry.state_value(:synced) }
last_synced_at { 5.days.ago }
end
trait :failed do
state { Geo::PackageFileRegistry.state_value(:failed) }
last_synced_at { 1.day.ago }
retry_count { 2 }
last_sync_failure { 'Random error' }
end
trait :started do
state { Geo::PackageFileRegistry.state_value(:started) }
last_synced_at { 1.day.ago }
retry_count { 0 }
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Geo::PackageFileRegistry, :geo, type: :model do
let_it_be(:registry) { create(:package_file_registry) }
specify 'factory is valid' do
expect(registry).to be_valid
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment