I'm writing a Python/MongoDB/AWS Lambda application to store appointment info in a DB, with the option to have another appointment 'prioritized' over it (by using a key value called 'priority').
As part of the implementation, I have a function called get_next, which pulls the next open appointment from the DB and returns it (if no prioritized appointment) or the prioritized appointment if it exists.
def get_next(self, appointmentid= None):
keydict = {
'sessionid' : self.info['id'],
'status' : 'open'
}
if appointmentid not in (None, ''):
keydict.update({'appointmentid' : appointmentid })
next_in_queue = self.db.getdetailsbykey("appointments", keydict, sortfield='_id', asc=False, suppressid=True)
if 'priority' in next_in_queue and next_in_queue['priority'] not in ('', None):
priority = self.get_next(appointmentid=next_in_queue['priority'])
if priority is not None:
return priority
return next_in_queue
Here getdetailsbykey is a wrapper around PyMongo's find_one:
def getdetailsbykey(self, collection_name, keydict, sortfield=None, asc=False, suppressid = True):
#if 'dict' not in str(type(keydict)):
if type(keydict) is not dict:
return None
#collection = self.db[collection_name]
collection = self.db[collection_name].with_options(codec_options=CodecOptions(tz_aware=True, tzinfo=timezone))
if sortfield is None:
if suppressid:
data = collection.find_one(keydict, {'_id' : 0})
else:
data = collection.find_one(keydict)
else:
if asc is True:
sortoption = 1
else:
sortoption = -1
if suppressid:
data = collection.find_one(keydict, {'_id' : 0}, sort=[(sortfield, sortoption)], )
else:
data = collection.find_one(keydict, sort=[(sortfield, sortoption)])
return data
However, as is obvious, this is susceptible to a 'loop' issue if there is ever a circular arrangement of appointments in priority. Usually, I'd address this using a global variable but in this case I'm not so sure as this will be an application running on an AWS lambda instance, so my question is - will instances share the variable (and hence the value - which would be a Bad Thing(tm) ) ??
I would use a loop to do this instead of recursion, but I feel recursion is a better way to handle this as compared to a loop.
EDIT/UPDATE: The closest I have come to a solution is the following:
def get_next(self, appointmentid= None, ref_appt = None):
keydict = {
'sessionid' : self.info['id'],
'$or' : [{ 'status' : 'open'}, { 'status' : 'inprogress'}]
}
if appointmentid not in (None, ''): # if we have a specific id
keydict.pop('$or', None)
keydict.update({'id' : appointmentid }) # retrieve it
next_in_queue = self.db.getdetailsbykey("appointments", keydict, sortfield='_id', asc=False, suppressid=True)
if ref_appt is None: # if this is the 0th level of recursion
ref_appt = next_in_queue['id'] #save the id
if next_in_queue is not None and 'priority' in next_in_queue and next_in_queue['priority'] not in ('', None): # if there is a higher priority appointment
priority = self.get_next(appointmentid=next_in_queue['priority'], ref_appt= ref_appt])
if priority is not None: # retrieve the appointment
if ref_appt != priority['id']:
return priority # if there is a circular loop, this will not execute
return next_in_queue
This should cause the last but one element in the loop to be returned, should a loop exist. However, my core question still stands - does the global variable in a python application with potentially multiple instances get shared across instances?
Any pointers/inputs would be very welcome.