From a998246b9cde0d32b039eed1541a38121af9b136 Mon Sep 17 00:00:00 2001 From: platon Date: Fri, 15 Jun 2018 15:17:57 +0300 Subject: [PATCH 1/4] Add resubscriptions for inserted commands --- devicehive/api.py | 43 ++++++++++++++++++++++++++++++++++---- devicehive/api_handler.py | 2 +- devicehive/subscription.py | 12 +++++------ 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/devicehive/api.py b/devicehive/api.py index 0175fa4..7cabe70 100644 --- a/devicehive/api.py +++ b/devicehive/api.py @@ -35,8 +35,37 @@ def __init__(self, transport, auth): self._transport = transport self._token = Token(self, auth) self._connected = True + self._subscription_calls = {self.subscribe_insert_commands: {}, + self.subscribe_update_commands: {}, + self.subscribe_notifications: {}} self.server_timestamp = None + @staticmethod + def _hashable_args(args): + args = list(args) + for i in range(len(args)): + if not isinstance(args[i], list): + continue + args[i] = tuple(args[i]) + return tuple(args) + + def _set_subscription_call(self, call, args): + args = self._hashable_args(args) + if args in self._subscription_calls[call]: + return + self._subscription_calls[call][args] = None + + def remove_subscription_call(self, call, args): + args = self._hashable_args(args) + if args not in self._subscription_calls[call]: + return + del self._subscription_calls[call][args] + + def apply_subscription_calls(self): + for call in self._subscription_calls: + for args in self._subscription_calls[call]: + call(*args) + @property def transport(self): return self._transport @@ -127,8 +156,9 @@ def subscribe_insert_commands(self, device_id=None, network_ids=(), join_names = ','.join(map(str, names)) join_network_ids = ','.join(map(str, network_ids)) join_device_type_ids = ','.join(map(str, device_type_ids)) + request_timestamp = None if not timestamp: - timestamp = self.server_timestamp + request_timestamp = self.server_timestamp auth_subscription_api_request = AuthSubscriptionApiRequest(self) auth_subscription_api_request.action(action) auth_subscription_api_request.url('device/command/poll') @@ -137,7 +167,7 @@ def subscribe_insert_commands(self, device_id=None, network_ids=(), auth_subscription_api_request.param('deviceTypeIds', join_device_type_ids) auth_subscription_api_request.param('names', join_names) - auth_subscription_api_request.param('timestamp', timestamp) + auth_subscription_api_request.param('timestamp', request_timestamp) auth_subscription_api_request.response_key('command') api_request = ApiRequest(self) api_request.action('command/subscribe') @@ -145,10 +175,15 @@ def subscribe_insert_commands(self, device_id=None, network_ids=(), api_request.set('networkIds', network_ids) api_request.set('deviceTypeIds', device_type_ids) api_request.set('names', names) - api_request.set('timestamp', timestamp) + api_request.set('timestamp', request_timestamp) api_request.subscription_request(auth_subscription_api_request) subscription = api_request.execute('Subscribe insert commands failure.') - return CommandsSubscription(self, subscription) + call = self.subscribe_insert_commands + args = (device_id, network_ids, device_type_ids, names, timestamp) + commands_subscription = CommandsSubscription(self, subscription, + call, args) + self._set_subscription_call(call, args) + return commands_subscription def subscribe_update_commands(self, device_id=None, network_ids=(), device_type_ids=(), names=(), diff --git a/devicehive/api_handler.py b/devicehive/api_handler.py index 526f540..7cd68f6 100644 --- a/devicehive/api_handler.py +++ b/devicehive/api_handler.py @@ -48,10 +48,10 @@ def handle_connect(self): if self._api_init: server_timestamp = self._api.get_info()['server_timestamp'] self._api.server_timestamp = server_timestamp + self._api.apply_subscription_calls() if not self._handle_connect: self._handle_connect = True self._handler.handle_connect() - return def handle_event(self, event): api_event = ApiEvent(event) diff --git a/devicehive/subscription.py b/devicehive/subscription.py index becdded..ab97ebd 100644 --- a/devicehive/subscription.py +++ b/devicehive/subscription.py @@ -23,15 +23,13 @@ class BaseSubscription(object): ID_KEY = 'subscriptionId' - def __init__(self, api, subscription=None): + def __init__(self, api, subscription=None, call=None, args=None): self._api = api self._id = None - if subscription: - self._init(subscription) - - def _init(self, subscription): - self._id = subscription[self.ID_KEY] + self._id = subscription[self.ID_KEY] + self._call = call + self._args = args def _ensure_exists(self): if self._id: @@ -55,6 +53,8 @@ def remove(self): api_request.remove_subscription_request(remove_subscription_api_request) api_request.execute('Unsubscribe failure.') self._id = None + if self._call and self._args: + self._api.remove_subscription_call(self._call, self._args) class CommandsSubscription(BaseSubscription): From eb4285a73512a36894b7c77a3872b14992528086 Mon Sep 17 00:00:00 2001 From: platon Date: Fri, 15 Jun 2018 15:29:19 +0300 Subject: [PATCH 2/4] Add resubscriptions for updated commands and notifications --- devicehive/api.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/devicehive/api.py b/devicehive/api.py index 7cabe70..cd624bb 100644 --- a/devicehive/api.py +++ b/devicehive/api.py @@ -192,8 +192,9 @@ def subscribe_update_commands(self, device_id=None, network_ids=(), join_names = ','.join(map(str, names)) join_network_ids = ','.join(map(str, network_ids)) join_device_type_ids = ','.join(map(str, device_type_ids)) + request_timestamp = None if not timestamp: - timestamp = self.server_timestamp + request_timestamp = self.server_timestamp auth_subscription_api_request = AuthSubscriptionApiRequest(self) auth_subscription_api_request.action(action) auth_subscription_api_request.url('device/command/poll') @@ -203,7 +204,7 @@ def subscribe_update_commands(self, device_id=None, network_ids=(), auth_subscription_api_request.param('deviceTypeIds', join_device_type_ids) auth_subscription_api_request.param('names', join_names) - auth_subscription_api_request.param('timestamp', timestamp) + auth_subscription_api_request.param('timestamp', request_timestamp) auth_subscription_api_request.response_timestamp_key('lastUpdated') auth_subscription_api_request.response_key('command') api_request = ApiRequest(self) @@ -213,10 +214,15 @@ def subscribe_update_commands(self, device_id=None, network_ids=(), api_request.set('networkIds', network_ids) api_request.set('deviceTypeIds', device_type_ids) api_request.set('names', names) - api_request.set('timestamp', timestamp) + api_request.set('timestamp', request_timestamp) api_request.subscription_request(auth_subscription_api_request) subscription = api_request.execute('Subscribe update commands failure.') - return CommandsSubscription(self, subscription) + call = self.subscribe_update_commands + args = (device_id, network_ids, device_type_ids, names, timestamp) + commands_subscription = CommandsSubscription(self, subscription, + call, args) + self._set_subscription_call(call, args) + return commands_subscription def subscribe_notifications(self, device_id=None, network_ids=(), device_type_ids=(), names=(), @@ -225,8 +231,9 @@ def subscribe_notifications(self, device_id=None, network_ids=(), join_names = ','.join(map(str, names)) join_network_ids = ','.join(map(str, network_ids)) join_device_type_ids = ','.join(map(str, device_type_ids)) + request_timestamp = None if not timestamp: - timestamp = self.server_timestamp + request_timestamp = self.server_timestamp auth_subscription_api_request = AuthSubscriptionApiRequest(self) auth_subscription_api_request.action(action) auth_subscription_api_request.url('device/notification/poll') @@ -235,7 +242,7 @@ def subscribe_notifications(self, device_id=None, network_ids=(), auth_subscription_api_request.param('deviceTypeIds', join_device_type_ids) auth_subscription_api_request.param('names', join_names) - auth_subscription_api_request.param('timestamp', timestamp) + auth_subscription_api_request.param('timestamp', request_timestamp) auth_subscription_api_request.response_key('notification') api_request = ApiRequest(self) api_request.action('notification/subscribe') @@ -243,10 +250,16 @@ def subscribe_notifications(self, device_id=None, network_ids=(), api_request.set('networkIds', network_ids) api_request.set('deviceTypeIds', device_type_ids) api_request.set('names', names) - api_request.set('timestamp', timestamp) + api_request.set('timestamp', request_timestamp) api_request.subscription_request(auth_subscription_api_request) subscription = api_request.execute('Subscribe notifications failure.') - return NotificationsSubscription(self, subscription) + call = self.subscribe_notifications + args = (device_id, network_ids, device_type_ids, names, timestamp) + notifications_subscription = NotificationsSubscription(self, + subscription, + call, args) + self._set_subscription_call(call, args) + return notifications_subscription def list_devices(self, name=None, name_pattern=None, network_id=None, network_name=None, sort_field=None, sort_order=None, From f05cdbdc35d67da689eda949bce61fcc525b2679 Mon Sep 17 00:00:00 2001 From: platon Date: Mon, 18 Jun 2018 12:06:35 +0300 Subject: [PATCH 3/4] Use sets --- devicehive/api.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/devicehive/api.py b/devicehive/api.py index cd624bb..8fa5ba0 100644 --- a/devicehive/api.py +++ b/devicehive/api.py @@ -35,9 +35,9 @@ def __init__(self, transport, auth): self._transport = transport self._token = Token(self, auth) self._connected = True - self._subscription_calls = {self.subscribe_insert_commands: {}, - self.subscribe_update_commands: {}, - self.subscribe_notifications: {}} + self._subscription_calls = {self.subscribe_insert_commands: set(), + self.subscribe_update_commands: set(), + self.subscribe_notifications: set()} self.server_timestamp = None @staticmethod @@ -53,13 +53,13 @@ def _set_subscription_call(self, call, args): args = self._hashable_args(args) if args in self._subscription_calls[call]: return - self._subscription_calls[call][args] = None + self._subscription_calls[call].add(args) def remove_subscription_call(self, call, args): args = self._hashable_args(args) if args not in self._subscription_calls[call]: return - del self._subscription_calls[call][args] + self._subscription_calls[call].remove(args) def apply_subscription_calls(self): for call in self._subscription_calls: From 47464b13dfa7a21b89c8eeabb8e29ac871ed30d6 Mon Sep 17 00:00:00 2001 From: platon Date: Mon, 18 Jun 2018 12:35:32 +0300 Subject: [PATCH 4/4] Increase version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6580fda..61dc602 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ setup(name='devicehive', - version='2.1.4', + version='2.1.5', author='DataArt (http://dataart.com)', author_email='info@devicehive.com', url='https://devicehive.com',