Skip to content

Instantly share code, notes, and snippets.

@dmknoll06
Created April 12, 2018 22:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmknoll06/52b1676e283b0c2cc94bd1ee51e35931 to your computer and use it in GitHub Desktop.
Save dmknoll06/52b1676e283b0c2cc94bd1ee51e35931 to your computer and use it in GitHub Desktop.
# purpose of this is to show a simplified form of how i would organize routing of events to handlers
# e.g. creating agents or handlers for various pantheon events
# the usage is to call route() with an event payload. route will then call all relevant handlers with that payload
# sample stubbed handlers.
# in real life, these would be fancy and complicated. this is just to show the logic for choosing what to invoke so they are stubs
def notify(payload):
print "notifying {}".format(payload)
def provision(payload):
print "provisioning {}".format(payload)
# the data - a map that defines which handler(s) are invoked based on the event's payload
# idea is that as the set of handlers grows, can expand the list of data without touching the code
# could make it much fancier:
# - more metadata
# - fancier wildcard scheme / pattern matching
# - could move into a real data store, could put an admin ui over it, etc
WILDCARD = '*'
HANDLER_MAP = [
{
"program": "*",
"model": "task",
"event": "start",
"handler": notify,
},
{
"program": "google-regular",
"model": "task",
"event": "start",
"handler": provision,
},
]
REQUIRED_FIELDS = ["program", "model", "event"]
# determine if a handler is a match for the given payload
# current logic is that it must have identical values for all metadata in the payload, or have a wildcard for a value in the payload
def matcher(payload, row):
for key, value in payload.iteritems():
if row[key] != value and row[key] != WILDCARD:
return False
return True
# given a payload, call the appropriate handlers for it
def route(payload):
# reject payload if not a dictionary
if type(payload) is not dict or not all(k in payload for k in REQUIRED_FIELDS):
print "invalid payload"
return
# find appropriate routes
matches = filter(lambda r: matcher(payload, r), HANDLER_MAP)
# dispatch
for match in matches:
match["handler"](payload)
# code for demonstrating this stuff
# there is a list of tests, each represents a mock event payload that we'll route to the appropriate dispatchers
# tests include a payload with missing fields, and one that is the wrong data type
tests = [{
"program": "google-regular",
"model": "task",
"event": "start"
},
{
"program": "uber",
"model": "task",
"event": "start"
},
{
"program": "park",
"model": "task",
"event": "start"
},
# a broken payload with missing fields
{
"broken": "payload"
},
# a broken payload of the wrong data type
"invalid data type"
]
print "routing test"
print "============="
for test_payload in tests:
print "test payload:"
print test_payload
print "------------"
route(test_payload)
print "======DONE========\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment