Skip to content

Commit

Permalink
Adds config class, refactors ModelAdditions
Browse files Browse the repository at this point in the history
  • Loading branch information
paulnsorensen committed Oct 28, 2013
1 parent 1ec96dd commit 71c589e
Show file tree
Hide file tree
Showing 14 changed files with 233 additions and 153 deletions.
25 changes: 21 additions & 4 deletions lib/lifesaver.rb
@@ -1,24 +1,41 @@
require 'resque-loner'
require "lifesaver/version"
require "lifesaver/config"
require "lifesaver/marshal"
require "lifesaver/index_graph"
require "lifesaver/model_additions"
require "lifesaver/model/indexing_queuing"
require "lifesaver/model/indexing_notification"
require "lifesaver/index_worker"
require "lifesaver/visitor_worker"
require "lifesaver/railtie" if defined? Rails

module Lifesaver
extend self

@@suppress_indexing = false

def self.suppress_indexing
def suppress_indexing
@@suppress_indexing = true
end

def self.unsuppress_indexing
def unsuppress_indexing
@@suppress_indexing = false
end

def self.indexing_suppressed?
def indexing_suppressed?
@@suppress_indexing
end

def config=(options = {})
@config = Config.new(options)
end

def config
@config ||= Config.new
end

def configure
yield config
end

end
16 changes: 16 additions & 0 deletions lib/lifesaver/config.rb
@@ -0,0 +1,16 @@
module Lifesaver
# A container for configuration parameters
class Config
attr_accessor :notification_queue, :indexing_queue

def initialize(options = {})

@notification_queue = :lifesaver_notification
@indexing_queue = :lifesaver_indexing

options.each do |key, value|
public_send("#{key}=", value)
end
end
end
end
6 changes: 3 additions & 3 deletions lib/lifesaver/index_graph.rb
Expand Up @@ -2,7 +2,7 @@ module Lifesaver
class IndexGraph

def initialize(marshalled_models=[])
@stack = []
@queue = []
@visited_models = {}
@models_to_index = []

Expand All @@ -20,7 +20,7 @@ def initialize(marshalled_models=[])
end

def generate
while model = @stack.shift
while model = @queue.shift
@models_to_index << model if model.has_index?
add_unvisited_models(model, :on_notify)
end
Expand All @@ -31,7 +31,7 @@ def generate

def add_model(model)
visit_model(model)
@stack << model
@queue << model
end

def visit_model(model)
Expand Down
4 changes: 3 additions & 1 deletion lib/lifesaver/index_worker.rb
@@ -1,6 +1,8 @@
class Lifesaver::IndexWorker
include ::Resque::Plugins::UniqueJob
@queue = :lifesaver_indexing

def self.queue; ::Lifesaver.config.indexing_queue end

def self.perform(class_name, id, action)
klass = class_name.to_s.classify.constantize
case action.to_sym
Expand Down
96 changes: 96 additions & 0 deletions lib/lifesaver/model/indexing_notification.rb
@@ -0,0 +1,96 @@
module Lifesaver
module Model
module IndexingNotification
module ClassMethods

def notifies_for_indexing(*args)
self.notifiable_associations = { on_change: [], on_notify: [] }
options = args.pop if args.last.is_a?(Hash)

populate_notifiable_associations(:on_change, args)
populate_notifiable_associations(:on_notify, args)

if options.present?
if options[:only_on_change].present?
populate_notifiable_associations(:on_change, options[:only_on_change])
end
if options[:only_on_notify].present?
populate_notifiable_associations(:on_notify, options[:only_on_notify])
end
end

notification_callbacks
end

private

def populate_notifiable_associations(key, associations)
if associations.is_a?(Array)
self.notifiable_associations[key] |= associations
else
self.notifiable_associations[key] << associations
end
end

def notification_callbacks(options={})
after_save do
send :update_associations, options.merge(operation: :update)
end
before_destroy do
send :update_associations, options.merge(operation: :destroy)
end
end
end

def self.included(base)
base.class_attribute :notifiable_associations
base.notifiable_associations = { on_change: [], on_notify: [] }
base.extend(ClassMethods)
end


def association_models(assoc)
models = []
association = public_send(assoc.to_sym)
unless association.nil?
if association.respond_to?(:each)
association.each do |m|
models << m
end
else
models << association
end
end
models
end

private

def dependent_association_map
dependent = {}
self.class.reflect_on_all_associations.each do |assoc|
dependent[assoc.name.to_sym] = true if assoc.options[:dependent].present?
end
dependent
end

def update_associations(options)
models = []
if options[:operation] == :destroy
dependent = dependent_association_map
assoc_models = []
self.class.notifiable_associations[:on_change].each do |assoc|
assoc_models |= association_models(assoc) unless dependent[assoc]
end
assoc_models.each do |m|
models << Lifesaver::Marshal.dump(m, {status: :notified})
end
elsif options[:operation] == :update
models << Lifesaver::Marshal.dump(self, {status: :changed})
end

::Resque.enqueue(Lifesaver::VisitorWorker, models) unless models.empty?
end
end
end
end
63 changes: 63 additions & 0 deletions lib/lifesaver/model/indexing_queuing.rb
@@ -0,0 +1,63 @@
module Lifesaver
module Model
module IndexingQueuing
module ClassMethods

def enqueues_indexing(options = {})
indexing_callbacks
end

private

def indexing_callbacks(options={})
# after_commit?
after_save do
send :enqueue_indexing, options.merge(operation: :update)
end
after_destroy do
send :enqueue_indexing, options.merge(operation: :destroy)
end
end
end

def self.included(base)
base.extend(ClassMethods)
end

def has_index?
self.respond_to?(:tire)
end

def suppress_indexing
@indexing_suppressed = true
end

def unsuppress_indexing
@indexing_suppressed = false
end

private

def enqueue_indexing(opts)
if has_index? && !suppress_indexing?
::Resque.enqueue(
Lifesaver::IndexWorker,
self.class.name.underscore.to_sym,
self.id,
opts[:operation]
)
end
end

# def validate_options(options)
# # on: should only have active model callback verbs (create, update, destroy?)
# # after: (next versions after you use resque scheduler) time to schedule
# # only: specifies fields that trigger changes
# end

def suppress_indexing?
Lifesaver.indexing_suppressed? || @indexing_suppressed || false
end
end
end
end
133 changes: 0 additions & 133 deletions lib/lifesaver/model_additions.rb

This file was deleted.

0 comments on commit 71c589e

Please sign in to comment.