Class: PullPhonePresenceWorker

Inherits:
Object
  • Object
show all
Includes:
Sidekiq::Job
Defined in:
app/workers/pull_phone_presence_worker.rb

Overview

Sidekiq worker: pull employee presence FROM the PBX (Switchvox) into the CRM.

Inbound counterpart to SyncPhoneStatusWorker (which pushes CRM -> PBX). This
closes the inbound half of the phone-status sync so a presence change made in
the Sangoma phone app (Available / Away / DND) is reflected back in the CRM.

EmployeePhoneStatus#pull_presence updates the local record from the PBX and,
on a real change, fires the after_commit hooks that refresh the navbar
presence dot and record an EmployeePhoneStatusChange.

Constant Summary collapse

STAGGER_OFFSETS_SECONDS =

Cron's finest granularity is one minute, but we want ~15s presence latency.
The once-a-minute scheduler pass seeds these four staggered fan-out passes
so each agent is polled roughly every 15 seconds. Distinct per-offset args
("fanout:0" … "fanout:45") are required: the global
lock: :until_and_while_executing + client on_conflict: :log default would
otherwise dedupe four identical-arg passes down to one.

[0, 15, 30, 45].freeze
FANOUT_PREFIX =

Constant.

'fanout:'

Instance Method Summary collapse

Instance Method Details

#perform(arg = nil) ⇒ Object

Parameters:

  • arg (nil, String, Integer) (defaults to: nil)

    nil -> scheduler pass (from cron): seed the staggered fan-outs
    "fanout:" -> one fan-out pass: enqueue a per-employee pull for each agent
    Integer (emp id) -> leaf: pull that employee's presence from the PBX



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'app/workers/pull_phone_presence_worker.rb', line 31

def perform(arg = nil)
  case arg
  when nil
    STAGGER_OFFSETS_SECONDS.each do |secs|
      self.class.perform_in(secs, "#{FANOUT_PREFIX}#{secs}")
    end
  when /\A#{FANOUT_PREFIX}/o
    # One job per employee for isolation (a bad account_id can't block the rest).
    Employee.phone_enabled.active_employees.ids.each do |eid|
      self.class.perform_async(eid)
    end
  else
    # Leaf: pull one employee's presence from the PBX. Per-account Switchvox
    # faults (e.g. getInfo returning the benign "invalid account" code for a
    # stale switchvox_account_id) are handled inside Phone::Pbx#get_presence_status,
    # which silences them and returns nil rather than reporting to AppSignal (#6173).
    EmployeePhoneStatus.pull_presence(arg)
  end
end