2017-02-15 11 views
2

Я использовал AASM, чтобы сделать государственные машины в моем текущем проекте и задавался вопросом, что является лучшим способом автоматического вызова событий и перехода к следующему состоянию?Каков наилучший способ автоматического изменения состояния в AASM

Я рассматриваю 2 способа сделать это:

  1. Настройка фоновое задание периодически проверять при выполнении определенных условий, следовательно, называют событие, чтобы перейти к следующему состоянию.

  2. У вас есть before_save вызов метода, который пытается выполнить следующее событие подряд. С защитой от него это не удастся, если будут выполнены условия, в противном случае - изменения состояния, а в следующий раз, когда обновится модель, мы проверим новое событие.

Я склонялся к второму варианту, так как настройка очереди background_job только для событий перехода кажется излишним. Я не мог найти лучшие практики в этом отношении, поэтому мне хотелось бы узнать лучший подход и почему это так?

Пример

К примеру, мы имеем start_onboarding и complete_onboarding события. Я не хочу вручную вызывать эти события, но я хочу автоматически переходить между ожидающим -> in_progress -> завершенным событиями.

enum status: { 
    pending: 1, 
    in_progress: 2, 
    completed: 3 
    } 

    aasm column: :status, enum: true, whiny_transitions: false do 
    state :pending, initial: true 
    state :in_progress 
    state :completed 

    event :start_onboarding do 
     transitions from: :pending, to: :in_progress 
    end 

    event :complete_onboarding do 
     transitions from: :in_progress, 
        to: :completed, 
        if: :onboarding_completed? 
    end 
    end 
+1

Вы можете уточнить, что изменения могут произойти с тем, что объекты и как они соединены с Государственный аппарат? Пример может помочь придумать хорошее решение. Я не уверен, согласен ли я на 'before_save', но я согласен с тем, что какой-то шаблон наблюдателя лучше, чем у cron, как фоновая работа, потому что наблюдатель может обеспечить * реальное время *, тогда как задание cron всегда будет за. – spickermann

+0

Не могли бы вы объяснить немного больше о том, что именно вы хотите здесь сделать. Чтобы я мог дать вам полезный ответ. –

+0

Я просто ищу общее мнение о лучшей практике.Я добавил пример конечного автомата @PradeepAgrawal –

ответ

1

В подобной задаче:

Мы избавились от:

  • обратных вызовов для переключения состояний, потому что они приносят производительность деградировать
  • Прямого опрос (с фоновыми заданиями), поскольку она также снизить эксплуатационные расходы

Приходится использовать:

И код выглядел примерно так:

require 'active_record' 
require 'aasm' 
require 'sidekiq' 

class Task < ActiveRecord::Base 
    include AASM 

    establish_connection adapter: 'sqlite3', database: 'todo.db' 

    connection.create_table table_name, force: true do |t| 
    t.string :name,  null: false 
    t.string :aasm_state, null: false, index: true 
    t.datetime :expired_at, null: false 
    end 

    validates :name, :aasm_state, :expired_at, presence: true 

    aasm do 
    state :pending, initial: true 
    state :in_progress 
    state :completed 
    state :expired 

    event :run do 
     transitions to: :in_progress 
    end 

    event :complete do 
     transitions to: :completed 
    end 

    event :expire do 
     transitions to: :expired, unless: :completed? 
    end 
    end 
end 

class Task::ExpireJob 
    include Sidekiq::Worker 

    def perform task 
    task.expire! 
    end 
end 

class Task::CreationService 
    def self.create! params 
    task = Task.create! params 
    task.run! 
    Task::ExpireJob.perform_at task.expired_at, task 
    task 
    end 

    def self.complete! task 
    task.complete! 
    task 
    end 
end 

task = Task::CreationService.create! \ 
    name:  'first', 
    expired_at: DateTime.now + 30.seconds 

p task 
p Task::CreationService.complete! task 
+2

Отлично, это больше похоже на то, что я ищу. Не могли бы вы подробнее рассказать о том, какая производительность ухудшилась с помощью обратных вызовов и живого опроса? Также это просто или вы считаете, что есть другие недостатки в использовании обратных вызовов? Моя забота об обратных вызовах в целом заключается в отсутствии контроля над исполнением. –