autopush.websocket

Websocket Protocol handler and HTTP Endpoints for Connection Node

Private HTTP Endpoints

These HTTP endpoints are only for communication from endpoint nodes and must not be publicly exposed.

PUT /push/(uuid: uaid)

Send a notification to a connected client with the given uaid.

Status Codes:
PUT /notif/(uuid: uaid)

Trigger a stored notification check for a connected client.

Status Codes:
  • 200 OK – Client is connected, and has started checking.
  • 202 Accepted – Client is connected but busy, will check notifications when not busy.
  • 404 Not Found – Client is not connected to this node.
DELETE /notif/(uuid: uaid)/(int: connected_at)

Immediately drop a client of this uaid if its connection time matches the connected_at provided.

Websocket Protocol

class autopush.websocket.PushServerProtocol[source]

Main Websocket Connection Protocol

parent_class

alias of WebSocketServerProtocol

randrange(start, stop=None, step=1, _int=<type 'int'>, _maxwidth=9007199254740992L)

Choose a random item from range(start, stop[, step]).

This fixes the problem with randint() which includes the endpoint; in Python this is usually not what you want.

deferToThread(func, *args, **kwargs)[source]

deferToThread helper that tracks defers outstanding

deferToLater(when, func, *args, **kwargs)[source]

deferToLater helper that tracks defers outstanding

force_retry(func, *args, **kwargs)[source]

Forcefully retry a function in a thread until it doesn’t error

Note that this does not use self.deferToThread, so this will continue to retry even if the client drops.

base_tags

Property that uses None if there’s no tags due to a DataDog library bug

log_failure(failure, **kwargs)[source]

Log a twisted failure out through twisted’s log.failure

paused

Indicates if we are paused for output production or not

_sendAutoPing(*args, **kwargs)[source]

Override for sanity checking during auto-ping interval

sendClose(*args, **kwargs)[source]

Override to add tracker that ensures the connection is truly torn down

nukeConnection(*args, **kwargs)[source]

Aggressive connection shutdown using abortConnection if onClose still hadn’t run by this point

onConnect(*args, **kwargs)[source]

autobahn onConnect handler for when a connection has started

processHandshake(*args, **kwargs)[source]

Disable host port checking on nonstandard ports since some clients are buggy and don’t provide it

onMessage(*args, **kwargs)[source]

autobahn onMessage processor for incoming messages

timeoutConnection()[source]

Idle timer fired.

onAutoPingTimeout()[source]

Override to track that this shut-down is from a ping timeout

onClose(*args, **kwargs)[source]

autobahn onClose handler for shutting down the connection and any outstanding deferreds related to this connection

cleanUp(wasClean, code, reason)[source]

Thorough clean-up method to cancel all remaining deferreds, and send connection metrics in

_save_webpush_notif(notif)[source]

Save a direct_update webpush style notification

_save_simple_notif(channel_id, version)[source]

Save a simplepush notification

_lookup_node(results)[source]

Looks up the node to send a notify for it to check storage if connected

_trap_uaid_not_found(fail)[source]

Traps UAID not found error

_notify_node(result)[source]

Checks the result of lookup node to send the notify if the client is connected elsewhere now

returnError(messageType, reason, statusCode, close=True, message='', url='http://autopush.readthedocs.io/en/latest/api/websocket.html#private-http-endpoint')[source]

Return an error to a client, and optionally shut down the connection safely

err_overload(failure, message_type, disconnect=True)[source]

Handle database overloads and errors

If disconnect is False, the an overload error is returned and the client is not disconnected.

Otherwise, pause producing to cease incoming notifications while we wait a random interval up to 8 seconds before closing down the connection. Most clients wait up to 10 seconds for a command, but this is not a guarantee, so rather than never reply, we still shut the connection down.

Parameters:disconnect – Whether the client should be disconnected or not.
err_finish_overload(message_type)[source]

Close the connection down and resume consuming input after the random interval from a db overload

sendJSON(body)[source]

Send a Python dict as a JSON string in a websocket message

process_hello(data)[source]

Process a hello message

_register_user(existing_user=True)[source]

Register a returning or new user

_verify_user_record()[source]

Verify a user record is valid

Returns a record that is ready for registering in the database if the user record was found.

Return type:Item or None
err_hello(failure)[source]

errBack for hello failures

_check_other_nodes(result, url='http://autopush.readthedocs.io/en/latest/api/websocket.html#private-http-endpoint')[source]

callback to check other nodes for clients and send them a delete as needed

finish_hello(previous)[source]

callback for successful hello message, that sends hello reply

process_notifications()[source]

Run a notification check against storage

webpush_fetch()[source]

Helper to return an appropriate function to fetch messages

error_notifications(fail)[source]

errBack for notification check failing

error_notification_overload(fail)[source]

errBack for provisioned errors during notification check

error_message_overload(fail)[source]

errBack for handling excessive messages per UAID

finish_notifications(notifs)[source]

callback for processing notifications from storage

finish_webpush_notifications(result)[source]

WebPush notification processor

_rotate_message_table()[source]

Function to fire off a message table copy of channels + update the router current_month entry

_monthly_transition()[source]

Transition the client to use a new message month

Utilized to migrate a users channels to a new message month and update the router record reflecting the proper month.

This is a blocking function that does not run on the event loop.

_finish_monthly_transition(result)[source]

Mark the client as successfully transitioned and resume

error_monthly_rotation_overload(fail)[source]

Capture overload on monthly table rotation attempt

If a provision exdeeded error hits while attempting monthly table rotation, schedule it all over and re-scan the messages. Normal websocket client flow is returned in the meantime.

_send_ping()[source]

Helper for ping sending that tracks when the ping was sent

process_ping()[source]

Ping Handling

Clients in the wild have a bug that lowers their ping interval to 0. It will never increase for them, as there is no way to remedy this without causing the client to use drastically more battery/data-usage we send them a code 4774 close to signify that they should stop until network change.

No other client should ping more than once per minute, or we tell them to go away.

process_register(data)[source]

Process a register message

error_register(fail)[source]

errBack handler for registering to fail

finish_register(endpoint, chid)[source]

callback for successful endpoint creation, sends register reply

process_unregister(data)[source]

Process an unregister message

ack_update(update)[source]

Helper function for tracking ack’d updates

Returns either None, if no delete_notification call is needed, or a deferred for the delete_notification call if it was needed.

_handle_webpush_ack(chid, version, code)[source]

Handle clearing out a webpush ack

_handle_webpush_update_remove(result, chid, notif)[source]

Handle clearing out the updates_sent

It’s possible the client may leave before this runs, so this is wrapped in a try/except in case the tear-down of self has started.

_handle_simple_ack(chid, version, code)[source]

Handle clearing out a simple ack

process_ack(data)[source]

Process an ack message, delete notifications from storage if needed

process_nack(data)[source]

Process a nack message and log its contents

check_missed_notifications(results, resume=False)[source]

Check to see if notifications were missed

bad_message(typ, message=None, url='http://autopush.readthedocs.io/en/latest/api/websocket.html#private-http-endpoint')[source]

Error helper for sending a 401 status back

_newer_notification_sent(channel_id, version)[source]

Returns whether a newer channel_id/version has already been sent

send_notification(update)[source]

Utility function for external use

This function is called by the HTTP handler to deliver an incoming update notification from an endpoint.

HTTP Handlers

class autopush.websocket.RouterHandler(application, request, **kwargs)[source]

Router Handler

Handles routing a notification to a connected client from an endpoint.

put(uaid)[source]

HTTP Put

Attempt delivery of a notification to a connected client.

class autopush.websocket.NotificationHandler(application, request, **kwargs)[source]
put(uaid, *args)[source]

HTTP Put

Notify a connected client that it should check storage for new notifications.

delete(uaid, connected_at)[source]

HTTP Delete

Drop a connected client as the client has connected to a new node.

Utility Functions

autopush.websocket.ms_time()[source]

Return current time.time call as ms and a Python int

autopush.websocket.log_exception(func)[source]

Exception Logger Decorator for protocol methods