module JamRuby class Diagnostic < ActiveRecord::Base # occurs when the client does not see a heartbeat from the server in a while NO_HEARTBEAT_ACK = 'NO_HEARTBEAT_ACK' # occurs when the client sees the socket go down WEBSOCKET_CLOSED_REMOTELY = 'WEBSOCKET_CLOSED_REMOTELY' # occurs when the client makes the socket go down WEBSOCKET_CLOSED_LOCALLY = 'WEBSOCKET_CLOSED_LOCALLY' # occurs when the websocket-gateway has finally given up entirely on a connection with no heartbeats seen in a while EXPIRED_STALE_CONNECTION = 'EXPIRED_STALE_CONNECTION' # occurs when the websocket-gateway is trying to handle a heartbeat, but can't find any state for the user. # this implies a coding error MISSING_CLIENT_STATE = 'MISSING_CLIENT_STATE' # the underlying database connection is gone when the heartbeat comes in MISSING_CONNECTION = 'MISSING_CONNECTION' # websocket gateway did not recognize message. indicates out-of-date websocket-gateway UNKNOWN_MESSAGE_TYPE = 'UNKNOWN_MESSAGE_TYPE' # empty route_to in message; which is invalid. indicates programming error MISSING_ROUTE_TO = 'MISSING_ROUTE_TO' # websocket gateway got a client with the same client_id as an already-connected client DUPLICATE_CLIENT = 'DUPLICATE_CLIENT' # info about how the test went NETWORK_TEST_RESULT = 'NETWORK_TEST_RESULT' # step 2 of the FTUE... could the user select their gear? GEAR_SELECTION = 'GEAR_SELECTION' DIAGNOSTIC_TYPES = [NO_HEARTBEAT_ACK, WEBSOCKET_CLOSED_REMOTELY, EXPIRED_STALE_CONNECTION, MISSING_CLIENT_STATE, UNKNOWN_MESSAGE_TYPE, MISSING_ROUTE_TO, DUPLICATE_CLIENT, WEBSOCKET_CLOSED_LOCALLY, NETWORK_TEST_RESULT, GEAR_SELECTION] # creator types # CLIENT = 'client' WEBSOCKET_GATEWAY = 'websocket-gateway' CREATORS = [CLIENT, WEBSOCKET_GATEWAY] self.primary_key = 'id' self.inheritance_column = 'nothing' belongs_to :user, :inverse_of => :diagnostics, :class_name => "JamRuby::User", :foreign_key => "user_id" validates :user, :presence => true validates :type, :inclusion => {:in => DIAGNOSTIC_TYPES} validates :creator, :inclusion => {:in => CREATORS} validates :data, length: {maximum: 100000} def self.expired_stale_connection(user, context) Diagnostic.save(EXPIRED_STALE_CONNECTION, user, WEBSOCKET_GATEWAY, context.to_json) if user end def self.missing_client_state(user, context) Diagnostic.save(MISSING_CLIENT_STATE, user, WEBSOCKET_GATEWAY, context.to_json) if user end def self.missing_connection(user, context) Diagnostic.save(MISSING_CONNECTION, user, WEBSOCKET_GATEWAY, context.to_json) if user end def self.duplicate_client(user, context) Diagnostic.save(DUPLICATE_CLIENT, user, WEBSOCKET_GATEWAY, context.to_json) if user end def self.unknown_message_type(user, client_msg) Diagnostic.save(UNKNOWN_MESSAGE_TYPE, user, WEBSOCKET_GATEWAY, client_msg.to_json) if user end def self.missing_route_to(user, client_msg) Diagnostic.save(MISSING_ROUTE_TO, user, WEBSOCKET_GATEWAY, client_msg.to_json) if user end def self.save(type, user, creator, data) diagnostic = Diagnostic.new if user.class == String diagnostic.user_id = user else diagnostic.user = user end diagnostic.data = data diagnostic.type = type diagnostic.creator = creator diagnostic.save end end end