新手问题 homeland 里关于 elastic search 异步任务的一个疑问

woleon · 2018年08月09日 · 最后由 pinewong 回复于 2018年08月11日 · 1849 次阅读

homeland 中的 searchable.rb 的第 23 行,在对象被销毁后,会调用异步任务来更新 es 的 index,如图:

任务代码如下:

请问在执行任务的时候,这个对象是不是已经被销毁了,那又是如何取到这个 obj 的?求答疑,万分感谢~

app/models/concerns/soft_delete.rb
mimosa 回复

soft_delete.rb 里有 default_scope -> { where(deleted_at: nil) },在没有 unscoped 的情况下,find_by_id 会过滤掉被删除的数据,也就是 deleted_at 不为 null 的数据吧?

destroy 返回的是删除的对象吧

感觉异步更新索引不传递 record,而是在回调里构建好 elasticsearch 需要的数据传到 job 更好一点,可以很好的实现回调时 record 的状态和执行 job 时 record 的状态统一,避免了上述执行任务时记录已经不存在(或不统一)的情况:

# app/models/concerns/searchable.rb
after_destroy_commit do
  SearchIndexerJob.perform_later('delete', self.class.index_name, self.class.document_type, id)
end
# app/jobs/search_indexer_job.rb
def perform(operation, index, type, id, body = nil)
  client = Elasticsearch::Model.client
  case operation
  when 'delete'
    client.delete(index: index, type: type, id: id)
  end
end

关于软删除的问题,可以在软删除中添加 commit 回调,使得软删除和删除行为一致,然后就可以像上述一样当成普通删除处理了:

# app/models/concerns/soft_delete.rb
def destroy
  transaction do
    # 添加 destroy 回调
    run_callbacks(:destroy) do
      # 添加 transaction 的 commit 回调
      self.class.connection.add_transaction_record(self)
      # 给 commit 回调添加条件(on: :destroy)
      @_trigger_destroy_callback = if persisted?
                                     # 此处逻辑修改
                                     time = Time.zone.now
                                     update_columns(deleted_at: time, updated_at: time)
                                   else
                                     true
                                   end
      @destroyed = true
      freeze
    end
  end
end

上述代码都是在 Rails 5.2 的环境下测试的,其他版本细节可能会有所不同

需要 登录 后方可回复, 如果你还没有账号请 注册新账号