PageRenderTime 19ms CodeModel.GetById 11ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/scripts/circuits.bench

https://bitbucket.org/prologic/circuits/
Unknown | 342 lines | 261 code | 81 blank | 0 comment | 0 complexity | 73b36338da7294751a3f3bbc33c6f871 MD5 | raw file
  1#!/usr/bin/env python
  2# -*- coding: utf-8 -*-
  3# vim: set sw=3 sts=3 ts=3
  4
  5"""(Tool) Bench Marking Tool
  6
  7THis tool does some simple benchmaking of the circuits library.
  8"""
  9
 10import sys
 11import math
 12import time
 13import optparse
 14
 15try:
 16    import hotshot
 17    import hotshot.stats
 18except ImportError:
 19    hostshot = None
 20
 21try:
 22    import psyco
 23except ImportError:
 24    psyco = None
 25
 26from circuits import __version__ as systemVersion
 27from circuits import handler, Event, Component, Bridge, Manager, Debugger
 28
 29USAGE = "%prog [options]"
 30VERSION = "%prog v" + systemVersion
 31
 32ERRORS = [
 33        (0, "Cannot listen and connect at the same time!"),
 34        (1, "Invalid events spcified. Must be an integer."),
 35        (2, "Invalid time spcified. Must be an integer."),
 36        (3, "Invalid nthreads spcified. Must be an integer."),
 37        ]
 38
 39###
 40### Functions
 41###
 42
 43def duration(seconds):
 44    days = int(seconds / 60 / 60 / 24)
 45    seconds = (seconds) % (60 * 60 * 24)
 46    hours = int((seconds / 60 / 60))
 47    seconds = (seconds) % (60 * 60)
 48    mins = int((seconds / 60))
 49    seconds = int((seconds) % (60))
 50    return (days, hours, mins, seconds)
 51
 52def parse_options():
 53    """parse_options() -> opts, args
 54
 55    Parse the command-line options given returning both
 56    the parsed options and arguments.
 57    """
 58
 59    parser = optparse.OptionParser(usage=USAGE, version=VERSION)
 60
 61    parser.add_option("-l", "--listen",
 62            action="store_true", default=False, dest="listen",
 63            help="Listen on 0.0.0.0:8000 (UDP) to test remote events")
 64
 65    parser.add_option("-w", "--wait",
 66            action="store_true", default=False, dest="wait",
 67            help="Wait for remote nodes to conenct")
 68
 69    parser.add_option("-b", "--bind",
 70            action="store", type="string", default="0.0.0.0", dest="bind",
 71            help="Bind to address:[port] (UDP) to test remote events")
 72
 73    parser.add_option("-c", "--concurrency",
 74            action="store", type="int", default=1, dest="concurrency",
 75            help="Set concurrency level")
 76
 77    parser.add_option("-t", "--time",
 78            action="store", type="int", default=0, dest="time",
 79            help="Stop after specified elapsed seconds")
 80
 81    parser.add_option("-e", "--events",
 82            action="store", type="int", default=0, dest="events",
 83            help="Stop after specified number of events")
 84
 85    parser.add_option("-p", "--profile",
 86            action="store_true", default=False, dest="profile",
 87            help="Enable execution profiling support")
 88
 89    parser.add_option("-m", "--mode",
 90            action="store", type="choice", default="speed", dest="mode",
 91            choices=["sync", "speed", "latency"],
 92            help="Operation mode")
 93
 94    parser.add_option("-f", "--fill",
 95            action="store", type="int", default=0, dest="fill",
 96            help="No. of dummy events to fill queue with")
 97
 98    parser.add_option("-d", "--debug",
 99            action="store_true", default=False, dest="debug",
100            help="Enable debug mode")
101
102    parser.add_option("-s", "--speed",
103            action="store_true", default=False, dest="speed",
104            help="Enable psyco (circuits on speed!)")
105
106    parser.add_option("-o", "--output",
107            action="store", default=None, dest="output",
108            help="Specify output format")
109
110    parser.add_option("-q", "--quiet",
111            action="store_false", default=True, dest="verbose",
112            help="Suppress output")
113
114    opts, args = parser.parse_args()
115
116    if opts.listen and args:
117        parser.exit(ERRORS[0][0], ERRORS[0][1])
118
119    return opts, args
120
121###
122### Events
123###
124
125class Stop(Event): pass
126class Term(Event): pass
127class Hello(Event): pass
128class Received(Event): pass
129class Foo(Event): pass
130
131###
132### Components
133###
134
135class Base(Component):
136
137    def __init__(self, opts, *args, **kwargs):
138        super(Base, self).__init__(*args, **kwargs)
139
140        self.opts = opts
141
142class Sender(Base):
143
144    concurrency = 1
145
146    def received(self, message=""):
147        self.fire(Hello("hello"))
148
149class Receiver(Base):
150
151    def helo(self, address, port):
152        self.fire(Hello("hello"))
153
154    def hello(self, message=""):
155        self.fire(Received(message))
156
157class SpeedTest(Base):
158
159    def hello(self, message):
160        self.fire(Hello(message))
161
162class LatencyTest(Base):
163
164    t = None
165
166    def received(self, message=""):
167        print("Latency: %0.3f us" % ((time.time() - self.t) * 1e6))
168        time.sleep(1)
169        self.fire(Hello("hello"))
170
171    def hello(self, message=""):
172        self.t = time.time()
173        self.fire(Received(message))
174    
175class State(Base):
176
177    done = False
178
179    def stop(self):
180        self.fire(Term())
181
182    def term(self):
183        self.done = True
184
185class Monitor(Base):
186
187    sTime = sys.maxsize
188    events = 0
189    state = 0
190
191    def helo(self, *args, **kwargs):
192        if self.opts.verbose:
193            print("Resetting sTime")
194        self.sTime = time.time()
195
196    @handler(filter=True)
197    def event(self, *args, **kwargs):
198        self.events += 1
199
200###
201### Main
202###
203
204def main():
205    opts, args = parse_options()
206
207    if opts.speed and psyco:
208        psyco.full()
209
210    manager = Manager()
211
212    monitor = Monitor(opts)
213    manager += monitor
214
215    state = State(opts)
216    manager += state
217
218    if opts.debug:
219        manager += Debugger()
220
221    if opts.listen or args:
222        nodes = []
223        if args:
224            for node in args:
225                if ":" in node:
226                    host, port = node.split(":")
227                    port = int(port)
228                else:
229                    host = node
230                    port = 8000
231                nodes.append((host, port))
232
233        if opts.bind is not None:
234            if ":" in opts.bind:
235                address, port = opts.bind.split(":")
236                port = int(port)
237            else:
238                address, port = opts.bind, 8000
239
240        bridge = Bridge(bind=(address, port), nodes=nodes)
241        manager += bridge
242
243    if opts.mode.lower() == "speed":
244        if opts.verbose:
245            print("Setting up Speed Test...")
246        if opts.concurrency > 1:
247            for c in range(int(opts.concurrency)):
248                manager += SpeedTest(opts, channel=c)
249        else:
250            manager += SpeedTest(opts)
251        monitor.sTime = time.time()
252    elif opts.mode.lower() == "latency":
253        if opts.verbose:
254            print("Setting up Latency Test...")
255        manager += LatencyTest(opts)
256        monitor.sTime = time.time()
257    elif opts.listen:
258        if opts.verbose:
259            print("Setting up Receiver...")
260        if opts.concurrency > 1:
261            for c in range(int(opts.concurrency)):
262                manager += Receiver(opts, channel=c)
263        else:
264            manager += Receiver(opts)
265    elif args:
266        if opts.verbose:
267            print("Setting up Sender...")
268        if opts.concurrency > 1:
269            for c in range(int(opts.concurrency)):
270                manager += Sender(opts, channel=c)
271        else:
272            manager += Sender(opts)
273    else:
274        if opts.verbose:
275            print("Setting up Sender...")
276            print("Setting up Receiver...")
277        if opts.concurrency > 1:
278            for c in range(int(opts.concurrency)):
279                manager += Sender(channel=c)
280                manager += Receiver(opts, channel=c)
281        else:
282            manager += Sender(opts)
283            manager += Receiver(opts)
284        monitor.sTime = time.time()
285
286    if opts.profile:
287        if hotshot:
288            profiler = hotshot.Profile("bench.prof")
289            profiler.start()
290
291    if not opts.wait:
292        if opts.concurrency > 1:
293            for c in range(int(opts.concurrency)):
294                manager.push(Hello("hello"), "hello", c)
295        else:
296            manager.push(Hello("hello"))
297
298    while not state.done:
299        try:
300            manager.flush()
301
302            for i in range(opts.fill):
303                manager.push(Foo())
304
305            if opts.events > 0 and monitor.events > opts.events:
306                manager.push(Stop())
307            if opts.time > 0 and (time.time() - monitor.sTime) > opts.time:
308                manager.push(Stop())
309
310        except KeyboardInterrupt:
311            manager.push(Stop())
312
313    if opts.verbose:
314        print()
315
316    eTime = time.time()
317
318    tTime = eTime - monitor.sTime
319
320    events = monitor.events
321    speed = int(math.ceil(float(monitor.events) / tTime))
322
323    if opts.output:
324        print(opts.output % (events, speed, tTime))
325    else:
326        print("Total Events: %d (%d/s after %0.2fs)" % (events, speed, tTime))
327
328    if opts.profile and hotshot:
329        profiler.stop()
330        profiler.close()
331
332        stats = hotshot.stats.load("bench.prof")
333        stats.strip_dirs()
334        stats.sort_stats("time", "calls")
335        stats.print_stats(20)
336
337###
338### Entry Point
339###
340
341if __name__ == "__main__":
342    main()