Advertisement
Guest User

q test

a guest
Aug 27th, 2016
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.68 KB | None | 0 0
  1. #
  2. # Copyright (C) 2016 Jason Gray <jasonlevigray3@gmail.com>
  3. #
  4. #This program is free software: you can redistribute it and/or modify it
  5. #under the terms of the GNU General Public License version 3, as published
  6. #by the Free Software Foundation.
  7. #
  8. #This program is distributed in the hope that it will be useful, but
  9. #WITHOUT ANY WARRANTY; without even the implied warranties of
  10. #MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
  11. #PURPOSE.  See the GNU General Public License for more details.
  12. #
  13. #You should have received a copy of the GNU General Public License along
  14. #with this program.  If not, see <http://www.gnu.org/licenses/>.
  15. ### END LICENSE
  16.  
  17. import threading
  18. import queue
  19. import time
  20. import random
  21. import gi
  22. gi.require_version('Gtk', '3.0')
  23. from gi.repository import Gtk, GLib, Gio
  24.  
  25. class Result:
  26.     def __init__(self, condition, result):
  27.         self._result = result
  28.         self._condition = condition
  29.  
  30.     def release(self):
  31.         with self._condition:
  32.             self._condition.notify()
  33.             return self._result
  34.  
  35.  
  36. class Worker(threading.Thread):
  37.     def __init__(self):
  38.         super().__init__()
  39.         self.queue = queue.PriorityQueue()
  40.         self.fifo_priority = 0
  41.         self.daemon = True
  42.         self.start()
  43.        
  44.     def run(self):
  45.         while True:
  46.             priority, _, f, args, kwargs, on_done, cancellable = self.queue.get()
  47.             if not cancellable.is_cancelled():
  48.                 condition = threading.Condition()
  49.                 result = Result(condition, f(*args, **kwargs))
  50.                 if on_done is not None:
  51.                     GLib.idle_add(on_done, result, priority=priority)
  52.                     with condition:
  53.                         condition.wait()
  54.  
  55.     def queue_task(self, priority, f, args, kwargs, on_done, cancellable):
  56.         self.fifo_priority += 1
  57.         self.queue.put_nowait((priority, self.fifo_priority, f, args, kwargs, on_done, cancellable))
  58.  
  59. worker = Worker()
  60.  
  61. def GLib_async_queue(on_done=None, priority=GLib.PRIORITY_DEFAULT_IDLE):
  62.     def wrapper(f):
  63.         def run(*args, **kwargs):
  64.             cancellable = Gio.Cancellable()
  65.             worker.queue_task(priority, f, args, kwargs, on_done, cancellable)
  66.             return cancellable
  67.         return run
  68.     return wrapper
  69.  
  70. class QueueTest(Gtk.Window):
  71.     def __init__(self):
  72.         Gtk.Window.__init__(self, title='Queue Test')
  73.         self.time_sec = 0
  74.         self.start_time = None
  75.         self.canceled_call_counter = 0
  76.         self.call_order_counter = 0
  77.         self.return_order_counter = 0
  78.         self.complete_message = []
  79.         self.set_default_size(350, -1)
  80.         self.set_resizable(False)
  81.         self.set_border_width(10)
  82.         self.headerbar = Gtk.HeaderBar()
  83.         self.headerbar.set_show_close_button(True)
  84.         self.headerbar.set_title('Queue Test')
  85.         self.headerbar.set_subtitle('00:00:00')
  86.         self.set_titlebar(self.headerbar)
  87.         vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
  88.         self.add(vbox)
  89.         self.button = Gtk.Button.new_with_label('Get Queue Test Results')
  90.         self.button.connect('clicked', self.async_queue_test)
  91.         vbox.pack_start(self.button, False, False, 0)
  92.         self.label = Gtk.Label()
  93.         vbox.pack_start(self.label, True, True, 0)
  94.         GLib.timeout_add(1000, self.update_time)
  95.  
  96.     def async_queue_test(self, *ignore):
  97.         self.button.set_sensitive(False)
  98.         self.start_time = None
  99.         self.canceled_call_counter = 0
  100.         self.call_order_counter = 0
  101.         self.return_order_counter = 0
  102.         self.complete_message = []
  103.         self.label.set_label('')
  104.         self.complete_message = []
  105.  
  106.         def get_message(result):
  107.             priority, order_called = result.release()
  108.             self.return_order_counter += 1
  109.             message = '{} priority: Call order {}, return order {}.'.format(priority, order_called, self.return_order_counter)
  110.             self.complete_message.append(message)
  111.             if self.return_order_counter == (24 - self.canceled_call_counter):
  112.                 should_have_took = (24 - self.canceled_call_counter) * 0.25
  113.                 time_took = time.time() - self.start_time
  114.                 done_message = '\nQueued 24 random priority 0.25 sec tasks.\nRandomly cancelled {} of them.'.format(self.canceled_call_counter)
  115.                 time_message = '{}\nShould have taken about {} secs.\nActually took {} secs.'.format(done_message, should_have_took, time_took)
  116.                 self.complete_message.append(time_message)
  117.                 self.button.set_sensitive(True)
  118.             label_text = '\n'.join(self.complete_message)
  119.             self.label.set_label(label_text)
  120.  
  121.         @GLib_async_queue(on_done=get_message, priority=GLib.PRIORITY_HIGH)
  122.         def say_high(order_called):
  123.             time.sleep(0.25)
  124.             return 'High', order_called
  125.  
  126.         @GLib_async_queue(on_done=get_message, priority=GLib.PRIORITY_DEFAULT)
  127.         def say_default(order_called):
  128.             time.sleep(0.25)
  129.             return 'Default', order_called
  130.  
  131.         @GLib_async_queue(on_done=get_message, priority=GLib.PRIORITY_DEFAULT_IDLE)
  132.         def say_idle(order_called):
  133.             time.sleep(0.25)
  134.             return 'Idle', order_called        
  135.  
  136.         @GLib_async_queue(on_done=get_message, priority=GLib.PRIORITY_LOW)
  137.         def say_low(order_called):
  138.             time.sleep(0.25)
  139.             return 'Low', order_called
  140.  
  141.         def low():
  142.             return say_low(self.call_order_counter)
  143.  
  144.         def idle():
  145.             return say_idle(self.call_order_counter)
  146.  
  147.         def default():
  148.             return say_default(self.call_order_counter)
  149.  
  150.         def high():
  151.             return say_high(self.call_order_counter)
  152.  
  153.         called = []
  154.         self.start_time = time.time()
  155.         for call in (random.choice((high, default, idle, low)) for i in range(24)):
  156.             self.call_order_counter += 1
  157.             test_call = call()
  158.             called.append(test_call)
  159.  
  160.         for i in range(12):
  161.             random_call =  random.choice(called)
  162.             if not random_call.is_cancelled():
  163.                 self.canceled_call_counter += 1
  164.                 random_call.cancel()
  165.  
  166.     def update_time(self):
  167.         self.time_sec += 1
  168.         time_int = self.time_sec
  169.         s = time_int % 60
  170.         time_int //= 60
  171.         m = time_int % 60
  172.         time_int //= 60
  173.         h = time_int
  174.         self.headerbar.set_subtitle('{:02d}:{:02d}:{:02d}'.format(h, m, s))
  175.         return True
  176.  
  177. if __name__ == '__main__':
  178.     win = QueueTest()
  179.     win.connect('delete-event', Gtk.main_quit)
  180.     win.show_all()
  181.     Gtk.main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement