Skip to content

Commit 4badcb3

Browse files
committed
Merge branch 'Develop' into Feature/CQC_conditionals
2 parents c6d8adc + 8c805e2 commit 4badcb3

File tree

7 files changed

+51
-24
lines changed

7 files changed

+51
-24
lines changed

.bumpversion.cfg

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[bumpversion]
2+
current_version = 3.0.4
3+
commit = True
4+
tag = False
5+
6+
[bumpversion:file:cqc/__init__.py]
7+
8+
[bumpversion:file:README.md]
9+

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ For more details refer to the [documentation](https://softwarequtech.github.io/S
66
Upcoming
77
--------
88

9+
2019-10-16 (v3.0.4)
10+
-------------------
11+
- If a CQCConnection does not manage to connect to the cqc server, the used app ID is popped from the list of used ones, to be reused again.
12+
13+
2019-10-08 (v3.0.3)
14+
-------------------
15+
- Fixed bug that mixes up return messages for different application IDs
16+
917
2019-05-29 (v3.0.2)
1018
-------------------
1119
- Updated coinflip example and added CI.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# CQC (3.0.4)
2+
13
The classical-quantum combiner (CQC) interface is an interface between higher layers and hardware in a Quantum Internet. It comes with a Python, C and Rust library for constructing CQC messages. The Python library is definitely the best place to get started.
24

35
Documentation of CQC can be found at https://softwarequtech.github.io/SimulaQron/html/CQCInterface.html

cqc/MessageHandler.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2727
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828

29-
from abc import ABC, abstractmethod
30-
from collections import defaultdict
3129
import logging
30+
from collections import defaultdict
31+
from abc import ABC, abstractmethod
3232

3333
from cqc.cqcHeader import (
3434
CQCCmdHeader,
@@ -178,6 +178,7 @@ def __init__(self, factory):
178178

179179
# Convenience
180180
self.name = factory.name
181+
self.return_messages = defaultdict(list) # Dictionary of all cqc messages to return per app_id
181182

182183
# List of all cqc messages to return
183184
self.return_messages = []
@@ -191,38 +192,38 @@ def handle_cqc_message(self, header, message, transport=None):
191192
"""
192193
This calls the correct method to handle the cqcmessage, based on the type specified in the header
193194
"""
194-
self.return_messages = []
195-
195+
self.return_messages[header.app_id] = []
196196
if header.tp in self.messageHandlers:
197197
try:
198198
should_notify = yield self.messageHandlers[header.tp](header, message)
199199

200200
if should_notify:
201201
# Send a notification that we are done if successful
202202
logging.debug("CQC %s: Command successful, sent done.", self.name)
203-
self.return_messages.append(
203+
self.return_messages[header.app_id].append(
204204
self.create_return_message(header.app_id, CQC_TP_DONE, cqc_version=header.version))
205205
except UnknownQubitError:
206206
logging.error("CQC {}: Couldn't find qubit with given ID".format(self.name))
207-
self.return_messages.append(
207+
self.return_messages[header.app_id].append(
208208
self.create_return_message(header.app_id, CQC_ERR_UNKNOWN, cqc_version=header.version))
209209
except NotImplementedError:
210210
logging.error("CQC {}: Command not implemented yet".format(self.name))
211-
self.return_messages.append(
211+
self.return_messages[header.app_id].append(
212212
self.create_return_message(header.app_id, CQC_ERR_UNSUPP, cqc_version=header.version))
213213
except Exception as err:
214214
logging.error(
215215
"CQC {}: Got the following unexpected error when handling CQC message: {}".format(self.name, err)
216216
)
217-
self.return_messages.append(
217+
self.return_messages[header.app_id].append(
218218
self.create_return_message(header.app_id, CQC_ERR_GENERAL, cqc_version=header.version))
219219
else:
220220
logging.error("CQC %s: Could not find cqc type %d in handlers.", self.name, header.yp)
221-
self.return_messages.append(
221+
self.return_messages[header.app_id].append(
222222
self.create_return_message(header.app_id, CQC_ERR_UNSUPP, cqc_version=header.version))
223223

224-
def retrieve_return_messages(self):
225-
return self.return_messages
224+
def retrieve_return_messages(self, app_id):
225+
"""Retrieve the return messages of a given app_id"""
226+
return self.return_messages[app_id]
226227

227228
@staticmethod
228229
def create_return_message(app_id, msg_type, length=0, cqc_version=CQC_VERSION):
@@ -315,13 +316,13 @@ def _process_command(self, cqc_header, length, data, is_locked=False):
315316
if cmd.instr not in self.commandHandlers:
316317
logging.debug("CQC {}: Unknown command {}".format(self.name, cmd.instr))
317318
msg = self.create_return_message(cqc_header.app_id, CQC_ERR_UNSUPP, cqc_version=cqc_header.version)
318-
self.return_messages.append(msg)
319+
self.return_messages[cqc_header.app_id].append(msg)
319320
return False, 0
320321
try:
321322
succ = yield self.commandHandlers[cmd.instr](cqc_header, cmd, xtra)
322323
except NotImplementedError:
323324
logging.error("CQC {}: Command not implemented yet".format(self.name))
324-
self.return_messages.append(
325+
self.return_messages[cqc_header.app_id].append(
325326
self.create_return_message(cqc_header.app_id, CQC_ERR_UNSUPP, cqc_version=cqc_header.verstion))
326327
return False, 0
327328
except Exception as err:
@@ -331,7 +332,7 @@ def _process_command(self, cqc_header, length, data, is_locked=False):
331332
)
332333
)
333334
msg = self.create_return_message(cqc_header.app_id, CQC_ERR_GENERAL, cqc_version=cqc_header.version)
334-
self.return_messages.append(msg)
335+
self.return_messages[cqc_header.app_id].append(msg)
335336
return False, 0
336337

337338
if succ is False: # only if it explicitly is false, if succ is None then we assume it went fine
@@ -346,7 +347,7 @@ def handle_factory(self, header, data):
346347
# Get factory header
347348
if len(data) < header.length:
348349
logging.debug("CQC %s: Missing header(s) in factory", self.name)
349-
self.return_messages.append(
350+
self.return_messages[header.app_id].append(
350351
self.create_return_message(header.app_id, CQC_ERR_UNSUPP, cqc_version=header.version))
351352
return False
352353
fact_header = CQCFactoryHeader(data[:fact_l])
@@ -369,7 +370,7 @@ def handle_factory(self, header, data):
369370
logging.error(
370371
"CQC {}: Got the following unexpected error when processing factory: {}".format(self.name, err)
371372
)
372-
self.return_messages.append(
373+
self.return_messages[header.app_id].append(
373374
self.create_return_message(header.app_id, CQC_ERR_GENERAL, cqc_version=header.version))
374375
return False
375376

cqc/Protocol.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def dataReceived(self, data):
153153
def _parseData(self, header, data):
154154
try:
155155
yield self.messageHandler.handle_cqc_message(header, data)
156-
messages = self.messageHandler.retrieve_return_messages()
156+
messages = self.messageHandler.retrieve_return_messages(header.app_id)
157157
except Exception as e:
158158
raise e
159159

cqc/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '3.0.2'
1+
__version__ = '3.0.4'

cqc/pythonLib.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def __init__(self, name, socket_address=None, appID=None, pend_messages=False,
251251
self._appID = appID
252252
self._appIDs[name].append(self._appID)
253253

254-
# Buffer received data
254+
# Buffer received data
255255
self.buf = None
256256

257257
# ClassicalServer
@@ -310,6 +310,7 @@ def __init__(self, name, socket_address=None, appID=None, pend_messages=False,
310310
time.sleep(self._conn_retry_time)
311311
self._s.close()
312312
if not retry_connection:
313+
self.close(release_qubits=False)
313314
raise err
314315
except Exception as err:
315316
logging.warning("App {} : Critical error when connection to CQC server: {}".format(self.name, err))
@@ -369,21 +370,27 @@ def get_appID(self):
369370

370371
def close(self, release_qubits=True):
371372
"""
372-
Closes the connection. Releases all qubits
373+
Closes the connection. Releases all qubits and remove the app ID from the used app IDs.
373374
"""
374375
if release_qubits:
375376
self.release_all_qubits()
376377
self._s.close()
377-
try:
378-
self._appIDs[self.name].remove(self._appID)
379-
except ValueError:
380-
pass # Already closed
378+
self._pop_app_id()
381379

382380
self.closeClassicalServer()
383381

384382
for name in list(self._classicalConn):
385383
self.closeClassicalChannel(name)
386384

385+
def _pop_app_id(self):
386+
"""
387+
Removes the used appID from the list.
388+
"""
389+
try:
390+
self._appIDs[self.name].remove(self._appID)
391+
except ValueError:
392+
pass # Already removed
393+
387394
def startClassicalServer(self):
388395
"""
389396
Sets up a server for the application communication, if not already set up.

0 commit comments

Comments
 (0)