最近手頭有個需求是這樣的,按期檢查數據庫獲取失敗任務而且進行重啓。最先想到的是添加一個生產者&&消費者隊列,可是發現不少棘手的問題。python
1.重啓任務是調用的一個shell腳本而後在腳本中又調用python程序,因此任務完成的狀態回傳略糾結。shell
2.重啓任務有多種重啓方式,要根據任務的不一樣FailStat來判斷重啓方式,這樣的話隊列中不只要有任務名稱,還須要狀態碼數據庫
3.Python裏的原生Queue不會進行去重,可能會致使隊列中對失敗任務不管重啓成功與否會進行屢次重跑。app
在StackOverflow上看了一些文章,都是推薦拓展Queue,看了看Queue.Queue的源代碼,發現果真很適合拓展:ide
# Override these methods to implement other queue organizations # (e.g. stack or priority queue). # These will only be called with appropriate locks held # Initialize the queue representation def _init(self, maxsize): self.queue = deque() def _qsize(self, len=len): return len(self.queue) # Put a new item in the queue def _put(self, item): self.queue.append(item) # Get an item from the queue def _get(self): return self.queue.popleft()
So,本身經過字典來實現了一個相似鏈表的類,而後繼承Queue.Queue並重寫方法,實現了一個新的有序不重複隊列:blog
#!/usr/bin/env python # Filename:ordered_map_queue.py # -*- encoding:utf-8 -*- import sys import Queue class Link(): ''' No repeat link ''' def __init__(self): self.map = {} self.tail = "head" self.map["head"] = {"stat":0, "next":"null"} def __contains__(self,key): return key in self.map def __len__(self): return len(self.map)-1 def isEmpty(self): if self.getHead() == "null": return True else: return False def clearLink(self): self.map.clear() def getTail(self): return self.tail def getHead(self): return self.map["head"]["next"] def add(self, string): # self.test_output("OrderedMapQueue") args = string.split('\t') item = args[0] stat = args[1] if item not in self.map: self.map[item] = {"stat":stat, "next":"null"} self.map[self.tail]["next"] = item self.tail = item def pop(self): if not self.isEmpty(): head_task = self.map["head"]["next"] rt_value = "%s\t%s" % (head_task, self.map[head_task]["stat"]) self.map["head"]["next"] = self.map[head_task]["next"] del self.map[head_task] if head_task == self.tail: self.tail = "head" return rt_value return None def test_output(self, name=""): print >>sys.stderr, name print >>sys.stderr, "-" * 10 + "TEST_OUTPUT" + "-" * 10 print >>sys.stderr, "Tail: %s\nHead: %s\nLength: %s" % (self.getTail(), self.getHead(), self.__len__()) head = "head" while head != "null": print >>sys.stderr, "%s\t%s\t%s" % (head, self.map[head]["stat"], self.map[head]["next"]) head = self.map[head]["next"] print >>sys.stderr, "-" * 31 class OrderedMapQueue(Queue.Queue): ''' ordered-map queue ''' def _init(self, maxsize=0): self.queue = Link() def _put(self, item): self.queue.add(item) def _get(self): return self.queue.pop() def _qsize(self): return self.queue.__len__() if __name__ == "__main__": #mylink = Link() #mylink.add("task1","-1") #mylink.add("task2","-2") #mylink.add("task3","-1") #mylink.test_output() myqueue = OrderedMapQueue() myqueue.put("task2\t-2") myqueue.put("task3\t-1") myqueue.put("task1\t-2") myqueue.put("task3\t-1") myqueue.put("task3\t-2") myqueue.queue.test_output() print myqueue.get() myqueue.queue.test_output() print myqueue.get() myqueue.queue.test_output() print myqueue.get() myqueue.queue.test_output()
本身菜鳥一隻,其中確定有很多問題或者可改進的,但願你們能多多支出,我定會認真修改,多謝~繼承
另外,推薦幾個拓展Queue的鏈接:隊列
http://stackoverflow.com/questions/16506429/check-if-element-is-already-in-a-queue/16506527#16506527utf-8
http://stackoverflow.com/questions/8482619/proper-way-to-extend-python-queueelement