Browse Source

Restored Python 3.7 support

This bug fix restores Python 3.7 support, which got compromised after the implementation of named tasks.

Signed-off-by: Stan Janssen <stan.janssen@elaad.nl>
Stan Janssen 4 years ago
parent
commit
45392e7c77
3 changed files with 42 additions and 22 deletions
  1. 15 11
      openleadr/client.py
  2. 7 5
      openleadr/server.py
  3. 20 6
      openleadr/service/event_service.py

+ 15 - 11
openleadr/client.py

@@ -14,14 +14,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""
-OpenADR Client for Python
-"""
-
 import asyncio
 import inspect
 import logging
 import ssl
+import sys
 import random
 from datetime import datetime, timedelta, timezone
 from functools import partial
@@ -151,9 +148,10 @@ class OpenADRClient:
             self.scheduler.shutdown()
         if self.report_queue_task:
             self.report_queue_task.cancel()
-        delayed_call_tasks = [task for task in asyncio.all_tasks() if task.get_name().startswith('DelayedCall')]
-        for task in delayed_call_tasks:
-            task.cancel()
+        if sys.version_info.minor > 8:
+            delayed_call_tasks = [task for task in asyncio.all_tasks() if task.get_name().startswith('DelayedCall')]
+            for task in delayed_call_tasks:
+                task.cancel()
         await self.client_session.close()
         await asyncio.sleep(0)
 
@@ -603,9 +601,12 @@ class OpenADRClient:
                 logger.info("The report is now complete with all the values. Will queue for sending.")
                 if self.allow_jitter:
                     delay = random.uniform(0, min(30, report_interval / 2))
+                    if sys.version_info.minor >= 8:
+                        name = {'name': f'DelayedCall-OutgoingReport-{utils.generate_id()}'}
+                    else:
+                        name = {}
                     self.loop.create_task(utils.delayed_call(func=self.pending_reports.put(outgoing_report),
-                                                             delay=delay),
-                                          name=f'DelayedCall-{utils.generate_id()}')
+                                                             delay=delay), **name)
                 else:
                     await self.pending_reports.put(self.incomplete_reports.pop(report_request_id))
             else:
@@ -615,9 +616,12 @@ class OpenADRClient:
             logger.info("Report will be sent now.")
             if self.allow_jitter:
                 delay = random.uniform(0, min(30, granularity.total_seconds() / 2))
+                if sys.version_info.minor >= 8:
+                    name = {'name': f'DelayedCall-OutgoingReport-{utils.generate_id()}'}
+                else:
+                    name = {}
                 self.loop.create_task(utils.delayed_call(func=self.pending_reports.put(outgoing_report),
-                                                         delay=delay),
-                                      name=f'DelayedCall-{utils.generate_id()}')
+                                                         delay=delay), **name)
             else:
                 await self.pending_reports.put(outgoing_report)
 

+ 7 - 5
openleadr/server.py

@@ -24,10 +24,11 @@ from functools import partial
 from datetime import datetime, timedelta, timezone
 from collections import deque
 import asyncio
+import inspect
 import logging
 import ssl
 import re
-import inspect
+import sys
 logger = logging.getLogger('openleadr')
 
 
@@ -144,10 +145,11 @@ class OpenADRServer:
         await self.run()
 
     async def stop(self):
-        delayed_call_tasks = [task for task in asyncio.all_tasks()
-                              if task.get_name().startswith('DelayedCall')]
-        for task in delayed_call_tasks:
-            task.cancel()
+        if sys.version_info.minor >= 8:
+            delayed_call_tasks = [task for task in asyncio.all_tasks()
+                                  if task.get_name().startswith('DelayedCall')]
+            for task in delayed_call_tasks:
+                task.cancel()
         await self.app_runner.cleanup()
 
     def add_event(self, ven_id, signal_name, signal_type, intervals, callback=None, event_id=None,

+ 20 - 6
openleadr/service/event_service.py

@@ -18,6 +18,7 @@ from . import service, handler, VTNService
 import asyncio
 from openleadr import objects, utils, enums
 import logging
+import sys
 from datetime import datetime, timezone
 from functools import partial
 from dataclasses import asdict
@@ -128,21 +129,34 @@ class EventService(VTNService):
         loop = asyncio.get_event_loop()
         now = datetime.now(timezone.utc)
         active_period = event.active_period
+
+        # Named tasks is only supported in Python 3.8+
+        if sys.version_info.minor >= 8:
+            named_tasks = True
+        else:
+            named_tasks = False
+            name = {}
+
         # Schedule status update to 'near' if applicable
         if active_period.ramp_up_period is not None and event.event_descriptor.event_status == 'far':
             ramp_up_start_delay = (active_period.dtstart - active_period.ramp_up_period) - now
             update_coro = partial(self._update_event_status, ven_id, event, 'near')
-            loop.create_task(utils.delayed_call(func=update_coro, delay=ramp_up_start_delay),
-                             name=f'DelayedCall-EventStatusToNear-{event.event_descriptor.event_id}')
+            if named_tasks:
+                name = {'name': f'DelayedCall-EventStatusToNear-{event.event_descriptor.event_id}'}
+            loop.create_task(utils.delayed_call(func=update_coro, delay=ramp_up_start_delay), **name)
+
         # Schedule status update to 'active'
         if event.event_descriptor.event_status in ('near', 'far'):
             active_start_delay = active_period.dtstart - now
             update_coro = partial(self._update_event_status, ven_id, event, 'active')
-            loop.create_task(utils.delayed_call(func=update_coro, delay=active_start_delay),
-                             name=f'DelayedCall-EventStatusToActive-{event.event_descriptor.event_id}')
+            if named_tasks:
+                name = {'name': f'DelayedCall-EventStatusToActive-{event.event_descriptor.event_id}'}
+            loop.create_task(utils.delayed_call(func=update_coro, delay=active_start_delay), **name)
+
         # Schedule status update to 'completed'
         if event.event_descriptor.event_status in ('near', 'far', 'active'):
             active_end_delay = active_period.dtstart + active_period.duration - now
             update_coro = partial(self._update_event_status, ven_id, event, 'completed')
-            loop.create_task(utils.delayed_call(func=update_coro, delay=active_end_delay),
-                             name=f'DelayedCall-EventStatusToCompleted-{event.event_descriptor.event_id}')
+            if named_tasks:
+                name = {'name': f'DelayedCall-EventStatusToActive-{event.event_descriptor.event_id}'}
+            loop.create_task(utils.delayed_call(func=update_coro, delay=active_end_delay), **name)