OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2011 Google Inc. All Rights Reserved. | 2 # Copyright 2011 Google Inc. All Rights Reserved. |
3 # | 3 # |
4 # Licensed under the Apache License, Version 2.0 (the "License"); | 4 # Licensed under the Apache License, Version 2.0 (the "License"); |
5 # you may not use this file except in compliance with the License. | 5 # you may not use this file except in compliance with the License. |
6 # You may obtain a copy of the License at | 6 # You may obtain a copy of the License at |
7 # | 7 # |
8 # http://www.apache.org/licenses/LICENSE-2.0 | 8 # http://www.apache.org/licenses/LICENSE-2.0 |
9 # | 9 # |
10 # Unless required by applicable law or agreed to in writing, software | 10 # Unless required by applicable law or agreed to in writing, software |
(...skipping 15 matching lines...) Expand all Loading... |
26 passed to ServerManager.Append() and by calling __enter__(). Once an | 26 passed to ServerManager.Append() and by calling __enter__(). Once an |
27 server's initializer is called successfully, the __exit__() function | 27 server's initializer is called successfully, the __exit__() function |
28 is guaranteed to be called when ServerManager.Run() completes. | 28 is guaranteed to be called when ServerManager.Run() completes. |
29 """ | 29 """ |
30 | 30 |
31 def __init__(self, is_record_mode): | 31 def __init__(self, is_record_mode): |
32 """Initialize a server manager.""" | 32 """Initialize a server manager.""" |
33 self.initializers = [] | 33 self.initializers = [] |
34 self.record_callbacks = [] | 34 self.record_callbacks = [] |
35 self.replay_callbacks = [] | 35 self.replay_callbacks = [] |
| 36 self.traffic_shapers = [] |
36 self.is_record_mode = is_record_mode | 37 self.is_record_mode = is_record_mode |
37 self.should_exit = False | 38 self.should_exit = False |
38 | 39 |
39 def Append(self, initializer, *init_args, **init_kwargs): | 40 def Append(self, initializer, *init_args, **init_kwargs): |
40 """Append a server to the end of the list to run. | 41 """Append a server to the end of the list to run. |
41 | 42 |
42 Servers start in the order they are appended and stop in the | 43 Servers start in the order they are appended and stop in the |
43 opposite order. | 44 opposite order. |
44 | 45 |
45 Args: | 46 Args: |
46 initializer: a function that returns a server instance. | 47 initializer: a function that returns a server instance. |
47 A server needs to implement the with-statement interface. | 48 A server needs to implement the with-statement interface. |
48 init_args: positional arguments for the initializer. | 49 init_args: positional arguments for the initializer. |
49 init_args: keyword arguments for the initializer. | 50 init_args: keyword arguments for the initializer. |
50 """ | 51 """ |
51 self.initializers.append((initializer, init_args, init_kwargs)) | 52 self.initializers.append((initializer, init_args, init_kwargs)) |
52 | 53 |
| 54 def AppendTrafficShaper(self, initializer, *init_args, **init_kwargs): |
| 55 """Append a traffic shaper to the end of the list to run. |
| 56 |
| 57 Args: |
| 58 initializer: a function that returns a server instance. |
| 59 A server needs to implement the with-statement interface. |
| 60 init_args: positional arguments for the initializer. |
| 61 init_args: keyword arguments for the initializer. |
| 62 """ |
| 63 self.traffic_shapers.append((initializer, init_args, init_kwargs)) |
| 64 |
53 def AppendRecordCallback(self, func): | 65 def AppendRecordCallback(self, func): |
54 """Append a function to the list to call when switching to record mode. | 66 """Append a function to the list to call when switching to record mode. |
55 | 67 |
56 Args: | 68 Args: |
57 func: a function that takes no arguments and returns no value. | 69 func: a function that takes no arguments and returns no value. |
58 """ | 70 """ |
59 self.record_callbacks.append(func) | 71 self.record_callbacks.append(func) |
60 | 72 |
61 def AppendReplayCallback(self, func): | 73 def AppendReplayCallback(self, func): |
62 """Append a function to the list to call when switching to replay mode. | 74 """Append a function to the list to call when switching to replay mode. |
(...skipping 21 matching lines...) Expand all Loading... |
84 | 96 |
85 def Run(self): | 97 def Run(self): |
86 """Create the servers and loop. | 98 """Create the servers and loop. |
87 | 99 |
88 The loop quits if a server raises an exception. | 100 The loop quits if a server raises an exception. |
89 | 101 |
90 Raises: | 102 Raises: |
91 any exception raised by the servers | 103 any exception raised by the servers |
92 """ | 104 """ |
93 server_exits = [] | 105 server_exits = [] |
| 106 server_ports = [] |
94 exception_info = (None, None, None) | 107 exception_info = (None, None, None) |
95 try: | 108 try: |
96 for initializer, init_args, init_kwargs in self.initializers: | 109 for initializer, init_args, init_kwargs in self.initializers: |
97 server = initializer(*init_args, **init_kwargs) | 110 server = initializer(*init_args, **init_kwargs) |
98 if server: | 111 if server: |
99 server_exits.insert(0, server.__exit__) | 112 server_exits.insert(0, server.__exit__) |
100 server.__enter__() | 113 server.__enter__() |
| 114 if hasattr(server, 'server_port'): |
| 115 server_ports.append(server.server_port) |
| 116 for initializer, init_args, init_kwargs in self.traffic_shapers: |
| 117 init_kwargs['ports'] = server_ports |
| 118 shaper = initializer(*init_args, **init_kwargs) |
| 119 if server: |
| 120 server_exits.insert(0, shaper.__exit__) |
| 121 shaper.__enter__() |
101 while True: | 122 while True: |
102 time.sleep(1) | 123 time.sleep(1) |
103 if self.should_exit: | 124 if self.should_exit: |
104 break | 125 break |
105 except: | 126 except: |
106 exception_info = sys.exc_info() | 127 exception_info = sys.exc_info() |
107 finally: | 128 finally: |
108 for server_exit in server_exits: | 129 for server_exit in server_exits: |
109 try: | 130 try: |
110 if server_exit(*exception_info): | 131 if server_exit(*exception_info): |
111 exception_info = (None, None, None) | 132 exception_info = (None, None, None) |
112 except: | 133 except: |
113 exception_info = sys.exc_info() | 134 exception_info = sys.exc_info() |
114 if exception_info != (None, None, None): | 135 if exception_info != (None, None, None): |
115 raise exception_info[0], exception_info[1], exception_info[2] | 136 raise exception_info[0], exception_info[1], exception_info[2] |
OLD | NEW |