1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-17 06:52:27 +01:00

[ongoing] elastic data structure for storing availabilities info

This commit is contained in:
Sylvain 2016-09-05 15:15:31 +02:00
parent 9ed8542e5d
commit 701b913eb1
5 changed files with 108 additions and 38 deletions

View File

@ -1,4 +1,10 @@
class Availability < ActiveRecord::Base
# elastic initialisations
include Elasticsearch::Model
index_name 'fablab'
document_type 'availabilities'
has_many :machines_availabilities, dependent: :destroy
has_many :machines, through: :machines_availabilities
accepts_nested_attributes_for :machines, allow_destroy: true
@ -24,6 +30,17 @@ class Availability < ActiveRecord::Base
validate :length_must_be_1h_minimum, unless: proc { end_at.blank? or start_at.blank? }
validate :should_be_associated
## elastic callbacks
after_save { AvailabilityIndexerWorker.perform_async(:index, self.id) }
after_destroy { AvailabilityIndexerWorker.perform_async(:delete, self.id) }
# elastic mapping
settings do
mappings dynamic: 'true' do
indexes 'available_type', analyzer: 'simple'
end
end
def safe_destroy
if available_type == 'machines'
reservations = Reservation.where(reservable_type: 'Machine', reservable_id: machine_ids).joins(:slots).where('slots.availability_id = ?', id)

View File

@ -52,8 +52,8 @@ class Project < ActiveRecord::Base
## elastic
# callbacks
after_save { IndexerWorker.perform_async(:index, self.id) }
after_destroy { IndexerWorker.perform_async(:delete, self.id) }
after_save { ProjectIndexerWorker.perform_async(:index, self.id) }
after_destroy { ProjectIndexerWorker.perform_async(:delete, self.id) }
#
settings do

View File

@ -0,0 +1,21 @@
class AvailabilityIndexerWorker
include Sidekiq::Worker
sidekiq_options queue: 'elasticsearch', retry: true
logger = Sidekiq.logger.level == Logger::DEBUG ? Sidekiq.logger : nil
client = Elasticsearch::Model.client
def perform(operation, record_id)
logger.debug [operation, "ID: #{record_id}"]
case operation.to_s
when /index/
record = Availability.find(record_id)
client.index index: Availability.index_name, type: Availability.document_type, id: record.id, body: record.as_indexed_json
#puts record.as_indexed_json
when /delete/
client.delete index: 'fablab', type: 'projects', id: record_id
else raise ArgumentError, "Unknown operation '#{operation}'"
end
end
end

View File

@ -1,4 +1,4 @@
class IndexerWorker
class ProjectIndexerWorker
include Sidekiq::Worker
sidekiq_options queue: 'elasticsearch', retry: true
@ -11,10 +11,9 @@ class IndexerWorker
case operation.to_s
when /index/
record = Project.find(record_id)
Client.index index: Project.index_name, type: Project.document_type, id: record.id, body: record.as_indexed_json
#puts record.as_indexed_json
Client.index index: Project.index_name, type: Project.document_type, id: record.id, body: record.to_json
when /delete/
Client.delete index: 'fablab', type: 'projects', id: record_id
Client.delete index: 'fablab', type: 'availabilities', id: record_id
else raise ArgumentError, "Unknown operation '#{operation}'"
end
end

View File

@ -1,42 +1,42 @@
namespace :fablab do
#desc "Get all stripe plans and create in fablab app"
#task stripe_plan: :environment do
#Stripe::Plan.all.data.each do |plan|
#unless Plan.find_by_stp_plan_id(plan.id)
#group = Group.friendly.find(plan.id.split('-').first)
#if group
#Plan.create(stp_plan_id: plan.id, name: plan.name, amount: plan.amount, interval: plan.interval, group_id: group.id, skip_create_stripe_plan: true)
#else
#puts plan.name + " n'a pas été créé. [error]"
#end
#end
#end
# desc "Get all stripe plans and create in fablab app"
# task stripe_plan: :environment do
# Stripe::Plan.all.data.each do |plan|
# unless Plan.find_by_stp_plan_id(plan.id)
# group = Group.friendly.find(plan.id.split('-').first)
# if group
# Plan.create(stp_plan_id: plan.id, name: plan.name, amount: plan.amount, interval: plan.interval, group_id: group.id, skip_create_stripe_plan: true)
# else
# puts plan.name + " n'a pas été créé. [error]"
# end
# end
# end
#
# if Plan.column_names.include? "training_credit_nb"
# Plan.all.each do |p|
# p.update_columns(training_credit_nb: (p.interval == 'month' ? 1 : 5))
# end
# end
# end
#if Plan.column_names.include? "training_credit_nb"
#Plan.all.each do |p|
#p.update_columns(training_credit_nb: (p.interval == 'month' ? 1 : 5))
#end
#end
#end
desc "Regenerate the invoices"
desc 'Regenerate the invoices'
task :regenerate_invoices, [:year, :month] => :environment do |task, args|
year = args.year || Time.now.year
month = args.month || Time.now.month
start_date = Time.new(year.to_i, month.to_i, 1)
end_date = start_date.next_month
puts "-> Start regenerate the invoices between #{I18n.l start_date, format: :long} in #{I18n.l end_date-1.minute, format: :long}"
invoices = Invoice.only_invoice.where("created_at >= :start_date AND created_at < :end_date", {start_date: start_date, end_date: end_date}).order(created_at: :asc)
invoices = Invoice.only_invoice.where('created_at >= :start_date AND created_at < :end_date', {start_date: start_date, end_date: end_date}).order(created_at: :asc)
invoices.each(&:regenerate_invoice_pdf)
puts "-> Done"
puts '-> Done'
end
desc "Cancel stripe subscriptions"
desc 'Cancel stripe subscriptions'
task cancel_subscriptions: :environment do
Subscription.where("expired_at >= ?", Time.now.at_beginning_of_day).each do |s|
Subscription.where('expired_at >= ?', Time.now.at_beginning_of_day).each do |s|
puts "-> Start cancel subscription of #{s.user.email}"
s.cancel
puts "-> Done"
puts '-> Done'
end
end
@ -96,17 +96,50 @@ namespace :fablab do
}';`
end
desc "sync all/one project in elastic search index"
desc 'sync all/one project in ElasticSearch index'
task :es_build_projects_index, [:id] => :environment do |task, args|
if Project.__elasticsearch__.client.indices.exists? index: 'fablab'
Project.__elasticsearch__.client.indices.delete index: 'fablab'
client = Project.__elasticsearch__.client
# create index if not exists
unless client.indices.exists? index: Project.index_name
client.indices.create Project.index_name
end
Project.__elasticsearch__.client.indices.create index: Project.index_name, body: { settings: Project.settings.to_hash, mappings: Project.mappings.to_hash }
# delete doctype if exists
if client.indices.exists_type? index: Project.index_name, type: Project.document_type
client.indices.delete_mapping index: Project.index_name, type: Project.document_type
end
# create doctype
client.indices.put_mapping index: Project.index_name, type: Project.document_type, body: { settings: Project.settings.to_hash, mappings: Project.mappings.to_hash }
# index requested documents
if args.id
IndexerWorker.perform_async(:index, id)
ProjectIndexerWorker.perform_async(:index, id)
else
Project.pluck(:id).each do |project_id|
IndexerWorker.perform_async(:index, project_id)
ProjectIndexerWorker.perform_async(:index, project_id)
end
end
end
desc 'sync all/one availabilities in ElasticSearch index'
task :es_build_availabilities_index, [:id] => :environment do |task, args|
client = Availability.__elasticsearch__.client
# create index if not exists
unless client.indices.exists? index: Availability.index_name
client.indices.create Availability.index_name
end
# delete doctype if exists
if client.indices.exists_type? index: Availability.index_name, type: Availability.document_type
client.indices.delete_mapping index: Availability.index_name, type: Availability.document_type
end
# create doctype
client.indices.put_mapping index: Availability.index_name, type: Availability.document_type, body: { settings: Availability.settings.to_hash, mappings: Availability.mappings.to_hash }
# index requested documents
if args.id
AvailabilityIndexerWorker.perform_async(:index, id)
else
Availability.pluck(:id).each do |availability_id|
AvailabilityIndexerWorker.perform_async(:index, availability_id)
end
end
end
@ -194,7 +227,7 @@ namespace :fablab do
puts "\nUsers successfully notified\n\n"
end
desc "generate fixtures from db"
desc 'generate fixtures from db'
task generate_fixtures: :environment do
Rails.application.eager_load!
ActiveRecord::Base.descendants.reject { |c| c == ActiveRecord::SchemaMigration or c == PartnerPlan }.each do |ar_base|