diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2018-12-24 16:34:32 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2018-12-26 11:10:33 +0000 |
commit | 2365e00b7c5e78f2ce5043a2e2495fef346ecb3d (patch) | |
tree | 57fa2b5228395bd94162c791eb580a04e4a15cc5 /bitbake/lib | |
parent | 5bc4f6935bf94b1d4e05e8652b5700f9fca389e5 (diff) | |
download | poky-2365e00b7c5e78f2ce5043a2e2495fef346ecb3d.tar.gz |
bitbake: process: Rewrite multiple connection handling
If the bitbake server recieved multiple connections, it currently closes
ones it can't handle (while its dealing with another). This is rather
antisocial behaviour which causes clients to quickly run through their
retries and abort.
Instead, queue any other connections until the current one is closed. This
way the client can decide when it wants to stop waiting for the server. If the
client is gone by the time we handle it, we handle that gracefully.
This also fixes a number of bugs in the connection handling where connections
which did drop early were badly handled causing tracebacks in the logs.
Also, handle queue incomming connections in a loop to ensure that the main
client handling doesn't starve that piece of the system.
This code was stress tested by running 50 connection attempts in parallel at
once, ensuring the code correctly handled them.
(Bitbake rev: 02845a561b38658ac3edf5cc9c34625ed860d34f)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
-rw-r--r-- | bitbake/lib/bb/server/process.py | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py index 1e4b51e35e..28b8eb9b86 100644 --- a/bitbake/lib/bb/server/process.py +++ b/bitbake/lib/bb/server/process.py | |||
@@ -130,6 +130,7 @@ class ProcessServer(multiprocessing.Process): | |||
130 | bb.utils.set_process_name("Cooker") | 130 | bb.utils.set_process_name("Cooker") |
131 | 131 | ||
132 | ready = [] | 132 | ready = [] |
133 | newconnections = [] | ||
133 | 134 | ||
134 | self.controllersock = False | 135 | self.controllersock = False |
135 | fds = [self.sock] | 136 | fds = [self.sock] |
@@ -138,37 +139,48 @@ class ProcessServer(multiprocessing.Process): | |||
138 | print("Entering server connection loop") | 139 | print("Entering server connection loop") |
139 | 140 | ||
140 | def disconnect_client(self, fds): | 141 | def disconnect_client(self, fds): |
141 | if not self.haveui: | ||
142 | return | ||
143 | print("Disconnecting Client") | 142 | print("Disconnecting Client") |
144 | fds.remove(self.controllersock) | 143 | if self.controllersock: |
145 | fds.remove(self.command_channel) | 144 | fds.remove(self.controllersock) |
146 | bb.event.unregister_UIHhandler(self.event_handle, True) | 145 | self.controllersock.close() |
147 | self.command_channel_reply.writer.close() | 146 | self.controllersock = False |
148 | self.event_writer.writer.close() | 147 | if self.haveui: |
149 | del self.event_writer | 148 | fds.remove(self.command_channel) |
150 | self.controllersock.close() | 149 | bb.event.unregister_UIHhandler(self.event_handle, True) |
151 | self.controllersock = False | 150 | self.command_channel_reply.writer.close() |
152 | self.haveui = False | 151 | self.event_writer.writer.close() |
153 | self.lastui = time.time() | 152 | self.command_channel.close() |
154 | self.cooker.clientComplete() | 153 | self.command_channel = False |
155 | if self.timeout is None: | 154 | del self.event_writer |
155 | self.lastui = time.time() | ||
156 | self.cooker.clientComplete() | ||
157 | self.haveui = False | ||
158 | ready = select.select(fds,[],[],0)[0] | ||
159 | if newconnections: | ||
160 | print("Starting new client") | ||
161 | conn = newconnections.pop(-1) | ||
162 | fds.append(conn) | ||
163 | self.controllersock = conn | ||
164 | elif self.timeout is None and not ready: | ||
156 | print("No timeout, exiting.") | 165 | print("No timeout, exiting.") |
157 | self.quit = True | 166 | self.quit = True |
158 | 167 | ||
159 | while not self.quit: | 168 | while not self.quit: |
160 | if self.sock in ready: | 169 | if self.sock in ready: |
161 | self.controllersock, address = self.sock.accept() | 170 | while select.select([self.sock],[],[],0)[0]: |
162 | if self.haveui: | 171 | controllersock, address = self.sock.accept() |
163 | print("Dropping connection attempt as we have a UI %s" % (str(ready))) | 172 | if self.controllersock: |
164 | self.controllersock.close() | 173 | print("Queuing %s (%s)" % (str(ready), str(newconnections))) |
165 | else: | 174 | newconnections.append(controllersock) |
166 | print("Accepting %s" % (str(ready))) | 175 | else: |
167 | fds.append(self.controllersock) | 176 | print("Accepting %s (%s)" % (str(ready), str(newconnections))) |
177 | self.controllersock = controllersock | ||
178 | fds.append(controllersock) | ||
168 | if self.controllersock in ready: | 179 | if self.controllersock in ready: |
169 | try: | 180 | try: |
170 | print("Connecting Client") | 181 | print("Processing Client") |
171 | ui_fds = recvfds(self.controllersock, 3) | 182 | ui_fds = recvfds(self.controllersock, 3) |
183 | print("Connecting Client") | ||
172 | 184 | ||
173 | # Where to write events to | 185 | # Where to write events to |
174 | writer = ConnectionWriter(ui_fds[0]) | 186 | writer = ConnectionWriter(ui_fds[0]) |