Created
April 12, 2018 22:44
-
-
Save dmknoll06/52b1676e283b0c2cc94bd1ee51e35931 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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