From 81c4672b152795ff8eb8dcbde5509927834c01ae Mon Sep 17 00:00:00 2001 From: jeffmellis Date: Fri, 31 Mar 2017 14:40:24 -0700 Subject: [PATCH 1/7] . --- .../runcode/transactionServer.py | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/transactionServer/runcode/transactionServer.py b/transactionServer/runcode/transactionServer.py index aa0271d..57b9405 100644 --- a/transactionServer/runcode/transactionServer.py +++ b/transactionServer/runcode/transactionServer.py @@ -10,27 +10,26 @@ import multiprocessing from multiprocessing import Process -# -# class rabbitConsumer(): -# def __init__(self, queueName,Q1, Q2, Q3): -# self.rabbitPQueue1 = Q1 -# self.rabbitPQueue2 = Q2 -# self.rabbitPQueue3 = Q3 -# self.connection = RabbitMQReceiver(self.consume, queueName) -# -# def consume(self, ch, method, props, body): -# payload = json.loads(body) -# print "Received :", payload -# print "priority = ",props.priority -# -# -# if props.priority == 1: -# self.rabbitPQueue1.put((1, payload)) -# elif props.priority == 2: -# self.rabbitPQueue2.put((2, payload)) -# else: -# self.rabbitPQueue3.put((3, payload)) +# userDisplaySummary shape: {userId: [command, command ...], ...} +class DisplaySummary(): + def __init__(self, max=10): + self.max = max + self.userDisplaySummary = {} + def addCommand(self, command): + userId = command["userId"] + + userSummary = self.userDisplaySummary.get(userId) + if not userSummary: + self.userDisplaySummary[userId] = [] + userSummary = self.userDisplaySummary[userId] + + userSummary.append(command) + if len(userSummary) > self.max: + del userSummary[0] + + def getDisplaySummary(self, userId): + return self.userDisplaySummary.get(userId) # quote shape: symbol: {value: string, retrieved: epoch time, user: string, cryptoKey: string} @@ -389,6 +388,9 @@ def handleCommandDumplog(args): auditClient.send(requestBody, 3) return "DUMPLOG SENT TO AUDIT" +def handleDisplaySummary(args): + userId = args["userId"] + return localDisplaySummary.getDisplaySummary(userId) def errorPrint(args, error): @@ -434,6 +436,10 @@ def delegate(ch , method, prop, args): # send command to audit, if it is from web server if prop == 1 or prop == 3: if args["command"] != "DUMPLOG": + # add command to local memory for the user + localDisplaySummary.addCommand(args) + + # send command to audit requestBody = auditFunctions.createUserCommand( int(time.time() * 1000), "transactionServer", @@ -518,6 +524,7 @@ def delegate(ch , method, prop, args): localQuoteCache = Quotes() + localDisplaySummary = DisplaySummary() functionSwitch = { "QUOTE": handleCommandQuote, @@ -534,7 +541,8 @@ def delegate(ch , method, prop, args): "SET_SELL_AMOUNT": handleCommandSetSellAmount, "CANCEL_SET_SELL": handleCommandCancelSetSell, "SET_SELL_TRIGGER": handleCommandSetSellTrigger, - "DUMPLOG": handleCommandDumplog + "DUMPLOG": handleCommandDumplog, + "DISPLAY_SUMMARY": handleDisplaySummary } From 0374801ef1789e936c41a5207f42928d2a1e3be5 Mon Sep 17 00:00:00 2001 From: jeffmellis Date: Sat, 1 Apr 2017 13:48:06 -0700 Subject: [PATCH 2/7] display summary also includes user object and buy/sell triggers now --- testfiles/displaySummary_workload.txt | 7 +++ transactionServer/runcode/mqDatabaseServer.py | 16 +++++++ transactionServer/runcode/mqTriggers.py | 43 ++++++++++++++++++- .../runcode/transactionServer.py | 22 +++++++++- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 testfiles/displaySummary_workload.txt diff --git a/testfiles/displaySummary_workload.txt b/testfiles/displaySummary_workload.txt new file mode 100644 index 0000000..89cd3cc --- /dev/null +++ b/testfiles/displaySummary_workload.txt @@ -0,0 +1,7 @@ +[1] ADD,oY01WVirLr,63511.53 +[2] QUOTE,oY01WVirLr,S +[3] SET_SELL_AMOUNT,oY01WVirLr,S,216.83 +[4] BUY,oY01WVirLr,S,303.83 +[5] SET_BUY_AMOUNT,oY01WVirLr,S,658.38 +[6] SET_SELL_TRIGGER,oY01WVirLr,S,30.04 +[7] DISPLAY_SUMMARY,oY01WVirLr \ No newline at end of file diff --git a/transactionServer/runcode/mqDatabaseServer.py b/transactionServer/runcode/mqDatabaseServer.py index 6929ede..54e950c 100644 --- a/transactionServer/runcode/mqDatabaseServer.py +++ b/transactionServer/runcode/mqDatabaseServer.py @@ -38,6 +38,7 @@ class databaseFunctions: RELEASE_PORTFOLIO = 13 BUY_TRIGGER = 14 SELL_TRIGGER = 15 + SUMMARY = 16 # @classmethod makes it so you dont have to instantiate the class. just call databaseFunctions.createAddRequest() @@ -199,6 +200,11 @@ def createSellTriggerRequest(cls, userId, costPer, portfolioCommitAmount, portfo 'symbol': symbol } + @classmethod + def createSummaryRequest(cls, userId, args): + args.update({'function': cls.SUMMARY, "userId": userId}) + return args + @classmethod def listOptions(cls): return [attr for attr in dir(databaseFunctions) if not callable(attr) and not attr.startswith("__") and attr != "listOptions" ] @@ -671,6 +677,15 @@ def handleTriggerSell(payload): return create_response(200, user) return create_response(400, "not enough portfolio reserved") +def handleSummary(payload): + userId = payload["userId"] + + user = databaseServer.getOrAddUser(userId) + payload['response'] = 200 + payload['user'] = user + + return payload + def on_request(ch, method, props, payload): print "payload: ", payload @@ -714,6 +729,7 @@ def on_request(ch, method, props, payload): databaseFunctions.RELEASE_PORTFOLIO: handleReleasePortfolio, databaseFunctions.BUY_TRIGGER: handleTriggerBuy, databaseFunctions.SELL_TRIGGER: handleTriggerSell, + databaseFunctions.SUMMARY: handleSummary, } # Object to send back to Transaction client print "create publisher" diff --git a/transactionServer/runcode/mqTriggers.py b/transactionServer/runcode/mqTriggers.py index 18c3875..fb0f07c 100644 --- a/transactionServer/runcode/mqTriggers.py +++ b/transactionServer/runcode/mqTriggers.py @@ -37,6 +37,7 @@ class TriggerFunctions: ACTIVATE_SELL = 5 CANCEL_SELL = 6 GET_SELL = 7 + SUMMARY = 8 @classmethod def createAddBuyRequest(cls, command, userId, stockSymbol, amount, lineNum): @@ -113,6 +114,11 @@ def createGetSellRequest(cls, command, userId, symbol, cash, lineNum): 'lineNum': lineNum, } + @classmethod + def createSummaryRequest(cls, userId, args): + args.update({'function': cls.SUMMARY, "userId": userId}) + return args + @classmethod def listOptions(cls): return [attr for attr in dir(databaseFunctions) if not callable(attr) and not attr.startswith("__") and attr != "listOptions" ] @@ -130,6 +136,15 @@ def getBuyTrigger(self, userId, symbol): if self._triggerExists(userId, symbol, self.buyTriggers): return self.buyTriggers[symbol][userId] + def getUserBuyTriggers(self, userId): + triggers = [] + for symbol in self.buyTriggers: + for user in self.buyTriggers[symbol]: + if user == userId: + triggers.append(self.buyTriggers[symbol][user]) + + return triggers + def getSellTriggers(self): return self.sellTriggers @@ -137,6 +152,15 @@ def getSellTrigger(self, userId, symbol): if self._triggerExists(userId, symbol, self.sellTriggers): return self.sellTriggers[symbol][userId] + def getUserSellTriggers(self, userId): + triggers = [] + for symbol in self.sellTriggers: + for user in self.sellTriggers[symbol]: + if user == userId: + triggers.append(self.sellTriggers[symbol][user]) + + return triggers + def addBuyTrigger(self, userId, sym, cashReserved, transactionNum): if sym not in self.buyTriggers: self.buyTriggers[sym] = {} @@ -379,6 +403,22 @@ def handleGetSell(payload): payload['errorString'] = "trigger doesnt exist" return payload +def handleSummary(payload): + # TODO: might have to hold onto triggers in 2 ways if it is a performance problem, currently have to look through all triggers to get single users + userId = payload["userId"] + + buyTriggers = triggers.getUserBuyTriggers(userId) + sellTriggers = triggers.getUserSellTriggers(userId) + + if buyTriggers and sellTriggers: + payload['response'] = 200 + payload['buyTriggers'] = buyTriggers + payload['sellTriggers'] = sellTriggers + else: + payload['response'] = 500 + payload['errorString'] = "error finding triggers" + return payload + def on_request(ch, method, props, payload): print "payload: ", payload @@ -408,7 +448,8 @@ def create_error_response(status, response): TriggerFunctions.SELL: handleAddSell, TriggerFunctions.ACTIVATE_SELL: handleSetSellActive, TriggerFunctions.CANCEL_SELL: handleCancelSell, - TriggerFunctions.GET_SELL: handleGetSell + TriggerFunctions.GET_SELL: handleGetSell, + TriggerFunctions.SUMMARY: handleSummary, } # self.start() currently commented out in both threads diff --git a/transactionServer/runcode/transactionServer.py b/transactionServer/runcode/transactionServer.py index 57b9405..26551b5 100644 --- a/transactionServer/runcode/transactionServer.py +++ b/transactionServer/runcode/transactionServer.py @@ -390,7 +390,27 @@ def handleCommandDumplog(args): def handleDisplaySummary(args): userId = args["userId"] - return localDisplaySummary.getDisplaySummary(userId) + + buyTriggers = args.get("buyTriggers") + sellTriggers = args.get("sellTriggers") + + user = args.get("user") + + if user is not None: + args["commandSummary"] = localDisplaySummary.getDisplaySummary(userId) + print "---response from handle summary---" + print args + return args + elif (buyTriggers is not None) and (sellTriggers is not None): + databaseClient.send( + databaseFunctions.createSummaryRequest(userId, args) + ) + else: + triggerClient.send( + TriggerFunctions.createSummaryRequest(userId, args) + ) + + return None def errorPrint(args, error): From 561aa30eccdb9930e167440ebb17502ba54813a5 Mon Sep 17 00:00:00 2001 From: jeffmellis Date: Sat, 1 Apr 2017 14:04:14 -0700 Subject: [PATCH 3/7] extra prints --- transactionServer/runcode/transactionServer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/transactionServer/runcode/transactionServer.py b/transactionServer/runcode/transactionServer.py index 26551b5..a44b165 100644 --- a/transactionServer/runcode/transactionServer.py +++ b/transactionServer/runcode/transactionServer.py @@ -389,12 +389,14 @@ def handleCommandDumplog(args): return "DUMPLOG SENT TO AUDIT" def handleDisplaySummary(args): + print "-- handle display summary--" userId = args["userId"] buyTriggers = args.get("buyTriggers") sellTriggers = args.get("sellTriggers") user = args.get("user") + print userId, buyTriggers, sellTriggers, user if user is not None: args["commandSummary"] = localDisplaySummary.getDisplaySummary(userId) From 7ab935249501f16a01108ef59bfd93507c11674f Mon Sep 17 00:00:00 2001 From: jeffmellis Date: Sat, 1 Apr 2017 14:14:18 -0700 Subject: [PATCH 4/7] on request was commented out --- transactionServer/runcode/mqTriggers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/transactionServer/runcode/mqTriggers.py b/transactionServer/runcode/mqTriggers.py index fb0f07c..144ea1e 100644 --- a/transactionServer/runcode/mqTriggers.py +++ b/transactionServer/runcode/mqTriggers.py @@ -431,6 +431,7 @@ def on_request(ch, method, props, payload): payload['errorString'] = "function not found" response = payload + print "reponse to transactionClient:", response transactionClient.send(response) @@ -476,7 +477,7 @@ def create_error_response(status, response): payload = msg[1] props = msg[0] print "queue size: ", P2Q_rabbit.qsize() - # on_request(None, None, props, payload) + on_request(None, None, props, payload) continue except: pass From 4a5307c110f52965e454fcd3c98097709a316170 Mon Sep 17 00:00:00 2001 From: jeffmellis Date: Sat, 1 Apr 2017 14:18:01 -0700 Subject: [PATCH 5/7] empty array is truthy false --- transactionServer/runcode/mqTriggers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/transactionServer/runcode/mqTriggers.py b/transactionServer/runcode/mqTriggers.py index 144ea1e..db89c17 100644 --- a/transactionServer/runcode/mqTriggers.py +++ b/transactionServer/runcode/mqTriggers.py @@ -410,7 +410,9 @@ def handleSummary(payload): buyTriggers = triggers.getUserBuyTriggers(userId) sellTriggers = triggers.getUserSellTriggers(userId) - if buyTriggers and sellTriggers: + print buyTriggers, sellTriggers + + if (buyTriggers is not None) and (sellTriggers is not None): payload['response'] = 200 payload['buyTriggers'] = buyTriggers payload['sellTriggers'] = sellTriggers From bf73d7b22017e9bb3efe195786ff1e6429427656 Mon Sep 17 00:00:00 2001 From: jeffmellis Date: Sat, 1 Apr 2017 14:24:06 -0700 Subject: [PATCH 6/7] extra command to check 10 --- testfiles/displaySummary_workload.txt | 8 +++++++- transactionServer/runcode/mqTriggers.py | 4 +--- transactionServer/runcode/transactionServer.py | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/testfiles/displaySummary_workload.txt b/testfiles/displaySummary_workload.txt index 89cd3cc..7eebade 100644 --- a/testfiles/displaySummary_workload.txt +++ b/testfiles/displaySummary_workload.txt @@ -4,4 +4,10 @@ [4] BUY,oY01WVirLr,S,303.83 [5] SET_BUY_AMOUNT,oY01WVirLr,S,658.38 [6] SET_SELL_TRIGGER,oY01WVirLr,S,30.04 -[7] DISPLAY_SUMMARY,oY01WVirLr \ No newline at end of file +[7] ADD,oY01WVirLr,63511.53 +[8] QUOTE,oY01WVirLr,S +[9] SET_SELL_AMOUNT,oY01WVirLr,S,216.83 +[10] BUY,oY01WVirLr,S,303.83 +[11] SET_BUY_AMOUNT,oY01WVirLr,S,658.38 +[12] SET_SELL_TRIGGER,oY01WVirLr,S,30.04 +[13] DISPLAY_SUMMARY,oY01WVirLr \ No newline at end of file diff --git a/transactionServer/runcode/mqTriggers.py b/transactionServer/runcode/mqTriggers.py index db89c17..6109f6c 100644 --- a/transactionServer/runcode/mqTriggers.py +++ b/transactionServer/runcode/mqTriggers.py @@ -410,8 +410,6 @@ def handleSummary(payload): buyTriggers = triggers.getUserBuyTriggers(userId) sellTriggers = triggers.getUserSellTriggers(userId) - print buyTriggers, sellTriggers - if (buyTriggers is not None) and (sellTriggers is not None): payload['response'] = 200 payload['buyTriggers'] = buyTriggers @@ -433,7 +431,7 @@ def on_request(ch, method, props, payload): payload['errorString'] = "function not found" response = payload - print "reponse to transactionClient:", response + print "response to transactionClient:", response transactionClient.send(response) diff --git a/transactionServer/runcode/transactionServer.py b/transactionServer/runcode/transactionServer.py index a44b165..4ae93e5 100644 --- a/transactionServer/runcode/transactionServer.py +++ b/transactionServer/runcode/transactionServer.py @@ -9,6 +9,7 @@ from threading import Thread import multiprocessing from multiprocessing import Process +from pprint import pprint # userDisplaySummary shape: {userId: [command, command ...], ...} class DisplaySummary(): @@ -402,6 +403,8 @@ def handleDisplaySummary(args): args["commandSummary"] = localDisplaySummary.getDisplaySummary(userId) print "---response from handle summary---" print args + pprint(args["commandSummary"]) + print len(args["commandSummary"]) return args elif (buyTriggers is not None) and (sellTriggers is not None): databaseClient.send( From eed55f543d92bb0149b84c2ee792c4f4011bb039 Mon Sep 17 00:00:00 2001 From: jeffmellis Date: Sat, 1 Apr 2017 14:28:46 -0700 Subject: [PATCH 7/7] removed some prints, now that its working --- transactionServer/runcode/transactionServer.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/transactionServer/runcode/transactionServer.py b/transactionServer/runcode/transactionServer.py index 4ae93e5..2240c15 100644 --- a/transactionServer/runcode/transactionServer.py +++ b/transactionServer/runcode/transactionServer.py @@ -390,7 +390,6 @@ def handleCommandDumplog(args): return "DUMPLOG SENT TO AUDIT" def handleDisplaySummary(args): - print "-- handle display summary--" userId = args["userId"] buyTriggers = args.get("buyTriggers") @@ -401,10 +400,6 @@ def handleDisplaySummary(args): if user is not None: args["commandSummary"] = localDisplaySummary.getDisplaySummary(userId) - print "---response from handle summary---" - print args - pprint(args["commandSummary"]) - print len(args["commandSummary"]) return args elif (buyTriggers is not None) and (sellTriggers is not None): databaseClient.send(