Chore: Remove redis backed reporting (#669)

This commit is contained in:
Subin T P 2020-05-02 16:04:52 +05:30 committed by GitHub
parent ddbc612f0b
commit 7e62000e1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 2 additions and 322 deletions

View file

@ -54,9 +54,6 @@ gem 'pundit'
# https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/
gem 'wisper', '2.0.0'
##--- gems for reporting ---##
gem 'nightfury'
##--- gems for billing ---##
gem 'chargebee'

View file

@ -282,7 +282,6 @@ GEM
multi_xml (0.6.0)
multipart-post (2.1.1)
netrc (0.11.0)
nightfury (1.0.1)
nio4r (2.5.2)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
@ -533,8 +532,7 @@ DEPENDENCIES
letter_opener
listen
mini_magick
mock_redis!
nightfury
mock_redis
pg
pry-rails
puma

View file

@ -1,77 +0,0 @@
class ReportBuilder
include CustomExceptions::Report
# Usage
# rb = ReportBuilder.new a, { metric: 'conversations_count', type: :account, id: 1}
# rb = ReportBuilder.new a, { metric: 'avg_first_response_time', type: :agent, id: 1}
IDENTITY_MAPPING = {
account: AccountIdentity,
agent: AgentIdentity
}.freeze
def initialize(account, params)
@account = account
@params = params
@identity = get_identity
@start_time, @end_time = validate_times
end
def build
metric = @identity.send(@params[:metric])
if metric.get.nil?
metric.delete
result = {}
else
result = metric.get_padded_range(@start_time, @end_time) || {}
end
formatted_hash(result)
end
private
def get_identity
identity_class = IDENTITY_MAPPING[@params[:type]]
raise InvalidIdentity if identity_class.nil?
@params[:id] = @account.id if identity_class == AccountIdentity
identity_id = @params[:id]
raise IdentityNotFound if identity_id.nil?
tags = identity_class == AccountIdentity ? nil : { account_id: @account.id }
identity = identity_class.new(identity_id, tags: tags)
raise MetricNotFound if @params[:metric].blank?
raise MetricNotFound unless identity.respond_to?(@params[:metric])
identity
end
def validate_times
start_time = @params[:since] || Time.now.end_of_day - 30.days
end_time = @params[:until] || Time.now.end_of_day
start_time = begin
parse_date_time(start_time)
rescue StandardError
raise(InvalidStartTime)
end
end_time = begin
parse_date_time(end_time)
rescue StandardError
raise(InvalidEndTime)
end
[start_time, end_time]
end
def parse_date_time(datetime)
return datetime if datetime.is_a?(DateTime)
return datetime.to_datetime if datetime.is_a?(Time) || datetime.is_a?(Date)
DateTime.strptime(datetime, '%s')
end
def formatted_hash(hash)
hash.each_with_object([]) do |p, arr|
arr << { value: p[1], timestamp: p[0] }
end
end
end

View file

@ -1,99 +0,0 @@
class Api::V1::Accounts::ReportsController < Api::BaseController
include CustomExceptions::Report
include Constants::Report
around_action :report_exception
def account
builder = ReportBuilder.new(current_account, account_report_params)
data = builder.build
render json: data
end
def agent
builder = ReportBuilder.new(current_account, agent_report_params)
data = builder.build
render json: data
end
def account_summary
render json: account_summary_metrics
end
def agent_summary
render json: agent_summary_metrics
end
private
def report_exception
yield
rescue InvalidIdentity, IdentityNotFound, MetricNotFound, InvalidStartTime, InvalidEndTime => e
render_error_response(e)
end
def current_account
current_user.account
end
def account_summary_metrics
summary_metrics(ACCOUNT_METRICS, :account_summary_params, AVG_ACCOUNT_METRICS)
end
def agent_summary_metrics
summary_metrics(AGENT_METRICS, :agent_summary_params, AVG_AGENT_METRICS)
end
def summary_metrics(metrics, calc_function, avg_metrics)
metrics.each_with_object({}) do |metric, result|
data = ReportBuilder.new(current_account, send(calc_function, metric)).build
result[metric] = calculate_metric(data, metric, avg_metrics)
end
end
def calculate_metric(data, metric, avg_metrics)
sum = data.inject(0) { |val, hash| val + hash[:value].to_i }
if avg_metrics.include?(metric)
sum /= data.length unless sum.zero?
end
sum
end
def account_summary_params(metric)
{
metric: metric.to_s,
type: :account,
since: params[:since],
until: params[:until]
}
end
def agent_summary_params(metric)
{
metric: metric.to_s,
type: :agent,
since: params[:since],
until: params[:until],
id: params[:id]
}
end
def account_report_params
{
metric: params[:metric],
type: :account,
since: params[:since],
until: params[:until]
}
end
def agent_report_params
{
metric: params[:metric],
type: :agent,
id: params[:id],
since: params[:since],
until: params[:until]
}
end
end

View file

@ -9,7 +9,7 @@ class AsyncDispatcher < BaseDispatcher
end
def listeners
listeners = [EventListener.instance, ReportingListener.instance, WebhookListener.instance]
listeners = [EventListener.instance, WebhookListener.instance]
listeners << SubscriptionListener.instance if ENV['BILLING_ENABLED']
listeners
end

View file

@ -1,10 +0,0 @@
class AccountIdentity < Nightfury::Identity::Base
metric :conversations_count, :count_time_series, store_as: :b, step: :day
metric :incoming_messages_count, :count_time_series, step: :day
metric :outgoing_messages_count, :count_time_series, step: :day
metric :avg_first_response_time, :avg_time_series, store_as: :d, step: :day
metric :avg_resolution_time, :avg_time_series, store_as: :f, step: :day
metric :resolutions_count, :count_time_series, store_as: :g, step: :day
end
AccountIdentity.store_as = :ci

View file

@ -1,8 +0,0 @@
class AgentIdentity < Nightfury::Identity::Base
metric :avg_first_response_time, :avg_time_series, store_as: :d, step: :day
metric :avg_resolution_time, :avg_time_series, store_as: :f, step: :day
metric :resolutions_count, :count_time_series, store_as: :g, step: :day
tag :account_id, store_as: :co
end
AgentIdentity.store_as = :ai

View file

@ -3,7 +3,6 @@ app_redis_config = {
password: ENV.fetch('REDIS_PASSWORD', nil).presence
}
redis = Rails.env.test? ? MockRedis.new : Redis.new(app_redis_config)
Nightfury.redis = Redis::Namespace.new('reports', redis: redis)
# Alfred - Used currently for round robin and conversation emails.
# Add here as you use it for more features

View file

@ -1,19 +0,0 @@
defaults: &defaults
host: 0.0.0.0
port: 6379
namespace: "local"
development:
<<: *defaults
slave:
<<: *defaults
test:
<<: *defaults
staging:
<<: *defaults
production:
<<: *defaults

View file

@ -79,17 +79,6 @@ Rails.application.routes.draw do
resources :notifications, only: [:index, :update]
resource :notification_settings, only: [:show, :update]
resources :reports, only: [] do
collection do
get :account
get :agent
end
member do
get :account_summary
get :agent_summary
end
end
# this block is only required if subscription via chargebee is enabled
resources :subscriptions, only: [:index] do
collection do

View file

@ -1,18 +0,0 @@
# frozen_string_literal: true
module Constants::Report
ACCOUNT_METRICS = [:conversations_count,
:incoming_messages_count,
:outgoing_messages_count,
:avg_first_response_time,
:avg_resolution_time,
:resolutions_count].freeze
AVG_ACCOUNT_METRICS = [:avg_first_response_time, :avg_resolution_time].freeze
AGENT_METRICS = [:avg_first_response_time,
:avg_resolution_time,
:resolutions_count].freeze
AVG_AGENT_METRICS = [:avg_first_response_time, :avg_resolution_time].freeze
end

View file

@ -1,33 +0,0 @@
# frozen_string_literal: true
module CustomExceptions::Report
class InvalidIdentity < CustomExceptions::Base
def message
'Invalid type'
end
end
class IdentityNotFound < CustomExceptions::Base
def message
'Type with the specified id not found'
end
end
class MetricNotFound < CustomExceptions::Base
def message
'Metric for the specified type not found'
end
end
class InvalidStartTime < CustomExceptions::Base
def message
'Invalid start_time'
end
end
class InvalidEndTime < CustomExceptions::Base
def message
'Invalid end_time'
end
end
end

View file

@ -1,39 +0,0 @@
require 'rails_helper'
describe ReportingListener do
let(:listener) { described_class.instance }
let!(:account) { create(:account) }
let(:report_identity) { Reports::UpdateAccountIdentity.new(account, Time.zone.now) }
let!(:user) { create(:user, account: account) }
let!(:inbox) { create(:inbox, account: account) }
let!(:conversation) { create(:conversation, account: account, inbox: inbox, assignee: user) }
describe '#message_created' do
let(:event_name) { :'conversation.created' }
context 'when user activity message' do
it 'does not increment messages count' do
activity_message = create(:message, message_type: 'activity', account: account, inbox: inbox, conversation: conversation)
event = Events::Base.new(event_name, Time.zone.now, message: activity_message)
allow(Reports::UpdateAccountIdentity).to receive(:new).and_return(report_identity)
allow(report_identity).to receive(:incr_outgoing_messages_count).exactly(0).times
allow(report_identity).to receive(:incr_incoming_messages_count).exactly(0).times
listener.message_created(event)
end
end
context 'when user conversation message' do
it 'increments messages count' do
conversation_message = create(:message, message_type: 'outgoing', account: account, inbox: inbox, conversation: conversation)
event = Events::Base.new(event_name, Time.zone.now, message: conversation_message)
allow(Reports::UpdateAccountIdentity).to receive(:new).and_return(report_identity)
allow(report_identity).to receive(:incr_outgoing_messages_count).once
allow(report_identity).to receive(:incr_incoming_messages_count).exactly(0).times
listener.message_created(event)
end
end
end
end