# For purposes of this document, the server will pass fields containing # mini-series, index, and a list of package-versions. # Status update will be given back slaveid, 'updatestatus', mini-series, index, and success/fail. # Requestwork will just ask for work. slaveid, 'requestwork' # Phase 1: # For the first phase assume we have a big array with configurations # of anchors (and only anchors) in descending lexicographic order. # So, lower indexes are lexicographically greater than later ones. # Call that configarray. # Toy configarray configarray = ['highconfig', 'midconfig', 'lowconfig'] # ??? Need Christophe to generate that. # In addition we have an array of statuses that is of the same size # and that is initialized to the value "undone". statusarray = ['undone' for n in range(len(configarray))] # Altogether there are three statuses: "undone", "success", "fail" currentindex = 0 foundbestanchor = False successfound = False # if some slave returns success then this is set to True successindex = 900000000 # index of lowest successful configuration while (not foundbestanchor): data = self.socket.recv() print(data) print('data are ', data) if not data: break fields = data.split(" ") print("fields are: ", fields) # format is slave number, opcode, args # opcodes can be 'requestwork' with argument or -1 # 'updatestatus' with arguments mini-series (-1 in first phase), # configindex and succeed(1) or fail(0) # numpart= ((fields[0]).split(":"))[1] if fields[1] == 'requestwork' and successfound: # Find anything lexicographically earlier has # not yet been done. # There must be something or the last statusupdate message # would have declared everything done. i = 0 worktodo = False while (i < successindex): if statusarray[i] == "undone": worktodo = True ret = [-1, i, configarray[i]] # the intent is to give configuration i; # The -1 shows the absence of a mini-series for the first phase print('ret from requestwork: ', ret) break i+= 1 assert worktodo == True # Otherwise would have left this first phase # when processing a status if fields[1] == 'requestwork' and not successfound: if (currentindex < len(configarray)): # Just send the next task in the configuration array ret = [-1, currentindex, configarray[currentindex]] print('ret from requestwork: ', ret) currentindex+= 1 else: # Have no more configs to try start again currentindex = 0 while (currentindex < len(configarray)) and (statusarray[currentindex] != "undone"): currentindex+= 1 if (currentindex < len(configarray)): ret = [-1, currentindex, configarray[currentindex]] else: print('Have exhausted the configuration array without finding anything') # ?? Christophe: error with indication of no configuration found # Status update will be given back slaveid, 'updatestatus', mini-series, index, and success/fail. if fields[1] == 'updatestatus': ret = [int[fields[3]], fields[4]] # index and success/fail if ret[1] == 'Success': statusarray[ret[0]] = 'success' # assumes first field of return is configindex successfound = True if (ret[0] < successindex): successindex = ret[0] if ret != 'Success': statusarray[ret[0]] = 'fail' if successfound: # check whether there is more work to do i = 0 worktodo = False while (i < successindex): if statusarray[i] == "undone": worktodo = True i+= 1 if not worktodo: foundbestanchor = True # successindex is the best # In this case we will go to the next loop. print("return value: ", ret) print("~~~~~~~~") self.socket.send("%s " % (ret)) # successindex has the configuration containing the best working anchors # We have an array # workinganchors with the versions from each package of the workinganchors. # corresponding to successindex. ?? Need Christophe # Now we need a function that extracts the best working mini-series for each # anchor. ?? Need Christophe. # workingmini = findworkingminiseries(successindex) workingmini = [[1,2,3], [2,3,4,5], [1,2,3,4,5]] numpackages = len(workingmini) # We also have an array of booleans called taketop which is True initially # because we have to start by taking the top one and becomes False # after our first optimistic foray. taketop = [True for i in range(numpackages)] # status for each package is 'available' means that this package has work to do # other status is 'working' meaning a slave is doing something for this package # 'found' meaning we've found the best version. status = ['available' for i in range(numpackages)] # Finally, we have bestconfig also of length numpackages which will have # the found version of each package. # It is initially filled with the versions of the best anchor # ??? Christophe bestconfig = ['unknown' for i in range(numpackages)] # Whenever a response comes back, if success, then we put the result # in bestconfig. If failure, we eliminate that config and all superior ones. # Fill in the versions for packages where there is only one version # If everything then we're done # numberleft is the number of packages on which we need to do binary search numberleft = 0 i = 0 while (i < numpackages): if len(miniseries[i]) == 1: bestconfig[i] = miniseries[i][0] status[i] = 'found' else: numberleft+= 1 i+= 1 packageindex = 0 while numberleft > 0: data = self.socket.recv() print(data) print('data are ', data) if not data: break fields = data.split(" ") print("fields are: ", fields) numpart= ((fields[0]).split(":"))[1] if (fields[1] == 'requestwork'): packageindex = 0 while (packageindex < numpackages) and (status[packageindex]) != 'available'): packageindex+=1 if (packageindex == numpackages): # nothing available but maybe something not found packageindex = 0 while (packageindex < numpackages) and (status[packageindex]) != 'found'): packageindex+=1 # The formconfig function takes all working anchors except for # the one for packageindex and builds a configuration from that if (packageindex < numpackages) and (taketop[packageindex] == True): taketop[packageindex] = False ret = [packageindex, -1, formconfig(packageindex, miniseries[packageindex][-1])] status[packageindex] = 'working' # start with the top of the mini-series elsif (packageindex < numpackages) and (taketop[packageindex] != True): mid = int(len(miniseries[packageindex])/2) ret = [packageindex, -1, formconfig(packageindex, miniseries[packageindex][mid])] status[packageindex] = 'working' else: print("Should not reach this, because we would only if everything found and then we'd be done") # Status update will be given back slaveid, 'updatestatus', mini-series, index, and success/fail. if fields[1] == 'updatestatus': ret = [int(fields[2]), int(fields[3]), fields[4]] # mini-series, index, success/fail print('ret from updatestatus: ', ret) if ret[2] == 'Success': status[ret[0]] = 'found' bestconfig[ret[0]] = miniseries[ret[0]][ret[1]] else: miniseries[ret[0]] = miniseries[ret[0]][0:ret[1]] # truncate up to but not including that index if len(miniseries[ret[0]]) > 1: status[ret[0]] = 'available' else: status[ret[0]] = 'found' bestconfig[ret[0]] = miniseries[ret[0]][0] # recalculate numberleft i = 0 numberleft = 0 while(i < numpackages): if (status[i] != 'found'): numberleft+= 1 i+= 1 self.socket.send("%s " % (ret)) # Confirmation: So now we have numberleft == 0 # Test bestconfig and if that doesn't succeed, replace bestconfig # with workingnchors. # Bestconfig will work if we were right about supplyconstant etc data = self.socket.recv() print(data) print('data are ', data) if not data: break fields = data.split(" ") print("fields are: ", fields) numpart= ((fields[0]).split(":"))[1] if (fields[1] == 'updatestatus'): # Status update will be given back slaveid, 'updatestatus', mini-series, index, and success/fail. ret = [int(fields[2]), int(fields[3]), fields[4]] if (ret[2] == -1): # this is the test on bestconfig if ret[4] == 'Success': print('Best config is: ' + bestconfig) else: print('Best config is: ' + workinganchors) if (fields[1] == 'requestwork'): ret = [-1, -1, bestconfig] self.socket.send("%s " % (ret))