diff --git a/ndn_python_repo/handle/read_handle.py b/ndn_python_repo/handle/read_handle.py index 2781e39..6b196a2 100644 --- a/ndn_python_repo/handle/read_handle.py +++ b/ndn_python_repo/handle/read_handle.py @@ -39,12 +39,11 @@ def unlisten(self, prefix): def _on_interest(self, int_name, int_param, _app_param): """ - Repo should not respond to any interest with MustBeFresh flag set. + Repo responds to Interests with mustBeFresh flag, following the same logic as the Content Store in NFD """ - if int_param.must_be_fresh: - logging.warn(f'Repo is configured to ignore Interests with MustBeFresh flag set: {Name.to_str(int_name)}') - return - data_bytes = self.storage.get_data_packet(int_name, int_param.can_be_prefix) + logging.debug(f'Repo got Interest with{"out" if not int_param.must_be_fresh else ""} ' + f'MustBeFresh flag set for name {Name.to_str(int_name)}') + data_bytes = self.storage.get_data_packet(int_name, int_param.can_be_prefix, int_param.must_be_fresh) if data_bytes == None: return self.app.put_raw_packet(data_bytes) diff --git a/ndn_python_repo/storage/leveldb.py b/ndn_python_repo/storage/leveldb.py index 5871597..7ecc761 100644 --- a/ndn_python_repo/storage/leveldb.py +++ b/ndn_python_repo/storage/leveldb.py @@ -59,14 +59,14 @@ def _get(self, key: bytes, can_be_prefix=False, must_be_fresh=False) -> bytes: if record == None: return None value, expire_time_ms = pickle.loads(record) - if not must_be_fresh or expire_time_ms != None and expire_time_ms > int(time.time() * 1000): + if not must_be_fresh or expire_time_ms is not None and expire_time_ms > self._time_ms(): return value else: return None else: for _, v_e in self.db.iterator(prefix=key): value, expire_time_ms = pickle.loads(v_e) - if not must_be_fresh or expire_time_ms != None and expire_time_ms > self.time_ms(): + if not must_be_fresh or expire_time_ms is not None and expire_time_ms > self._time_ms(): return value return None diff --git a/ndn_python_repo/storage/mongodb.py b/ndn_python_repo/storage/mongodb.py index af62446..9b6c0d6 100644 --- a/ndn_python_repo/storage/mongodb.py +++ b/ndn_python_repo/storage/mongodb.py @@ -81,7 +81,7 @@ def _get(self, key: bytes, can_be_prefix=False, must_be_fresh=False) -> Optional else: query.update({'key': {'$regex': '^' + key}}) if must_be_fresh: - query.update({'expire_time_ms': {'$gt': self.time_ms()}}) + query.update({'expire_time_ms': {'$gt': self._time_ms()}}) ret = self.c_collection.find_one(query) if ret: return ret['value'] diff --git a/ndn_python_repo/storage/sqlite.py b/ndn_python_repo/storage/sqlite.py index c655243..e288568 100644 --- a/ndn_python_repo/storage/sqlite.py +++ b/ndn_python_repo/storage/sqlite.py @@ -70,7 +70,7 @@ def _get(self, key: bytes, can_be_prefix=False, must_be_fresh=False) -> Optional c = self.conn.cursor() query = 'SELECT value FROM data WHERE ' if must_be_fresh: - query += f'(expire_time_ms > {time_ms()}) AND ' + query += f'(expire_time_ms > {self._time_ms()}) AND ' if can_be_prefix: query += 'hex(key) LIKE ?' c.execute(query, (key.hex() + '%', )) diff --git a/ndn_python_repo/storage/storage_base.py b/ndn_python_repo/storage/storage_base.py index 381b57c..d619143 100644 --- a/ndn_python_repo/storage/storage_base.py +++ b/ndn_python_repo/storage/storage_base.py @@ -97,6 +97,8 @@ def get_data_packet(self, name: NonStrictName, can_be_prefix: bool=False, :param must_be_fresh: bool. If true, ignore expired data. :return: The value of the data packet. """ + # can_be_prefix must be set to False by default because _delete_single_data would not otherwise be specific enough. + # must_be_fresh must be set to False by default because we want the delete commands to find data we want deleted, regardless of whether it is fresh or not. name = Name.normalize(name) if Component.get_type(name[-1]) == Component.TYPE_IMPLICIT_SHA256: data = self.get_data_packet(name[:-1], can_be_prefix, must_be_fresh) diff --git a/tests/storage_test.py b/tests/storage_test.py index 71aa1a1..092b7de 100644 --- a/tests/storage_test.py +++ b/tests/storage_test.py @@ -5,6 +5,7 @@ from ndn.encoding import Name from ndn_python_repo.storage import * import pytest +import time class StorageTestFixture(object): @@ -20,6 +21,7 @@ def test_main(_tmp_path): StorageTestFixture._test_remove() StorageTestFixture._test_get_data_packet() StorageTestFixture._test_freshness_period() + StorageTestFixture._test_freshness_period_again() StorageTestFixture._test_get_prefix() StorageTestFixture._test_put_batch() StorageTestFixture._test_write_back() @@ -64,7 +66,21 @@ def _test_freshness_period(): data_bytes_out = StorageTestFixture.storage.get_data_packet(Name.from_str('/test_freshness_period/1'), must_be_fresh=True) assert data_bytes_out == None - + + @staticmethod + def _test_freshness_period_again(): + # /test_get_data_packet/0, freshnessPeriod = 3000ms + data_bytes_in = b'\x06\xc3\x07\x1d\x08\x15test_freshness_period\x08\x0122\x01\x00\x14\x0c\x18\x01\x00\x19\x02\x0b\xb8\x1a\x032\x01\x00\x15\x0eHello, World!\n\x16;\x1b\x01\x03\x1c6\x074\x08\tlocalhost\x08\x08operator\x08\x03KEY\x08\x08\xd3\xe9x\xe9\x9cDR0\x08\x04self6\x08\x00\x00\x01\x92T\xa3\xa4\x01\x17G0E\x02!\x00\xcbUrj\xea.\x94\x98\xb5\xe5hG\x14\xad{\xdc|\x9c\xeb\xde\x83,YB?\x83\x1efA\xb8.\xde\x02 k\xd5N\xa0\xef\xa3\xcc~\xfe\xcc\x08,\x08]\tL\xeem\xeff\x9a\x9eoB\xbe\xe1\xae\x8c\x95M\xdb\x00' + StorageTestFixture.storage.put_data_packet(Name.from_str('/test_freshness_period/2'), data_bytes_in) + data_bytes_out = StorageTestFixture.storage.get_data_packet(Name.from_str('/test_freshness_period/2'), + must_be_fresh=True) + assert data_bytes_in == data_bytes_out + time.sleep(3) + data_bytes_out = StorageTestFixture.storage.get_data_packet(Name.from_str('/test_freshness_period/2'), + must_be_fresh=True) + assert data_bytes_out is None + + @staticmethod def _test_get_prefix(): # /test_get_prefix/0, freshnessPeriod = 10000ms