Passed
Push — main ( 972afa...bde4c8 )
by Yohann
01:49 queued 11s
created

pincer.core.heartbeat.Heartbeat.update_sequence()   A

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
# -*- coding: utf-8 -*-
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
# MIT License
3
#
4
# Copyright (c) 2021 Pincer
5
#
6
# Permission is hereby granted, free of charge, to any person obtaining
7
# a copy of this software and associated documentation files
8
# (the "Software"), to deal in the Software without restriction,
9
# including without limitation the rights to use, copy, modify, merge,
10
# publish, distribute, sublicense, and/or sell copies of the Software,
11
# and to permit persons to whom the Software is furnished to do so,
12
# subject to the following conditions:
13
#
14
# The above copyright notice and this permission notice shall be
15
# included in all copies or substantial portions of the Software.
16
#
17
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25
from __future__ import annotations
26
27
import logging
28
from asyncio import sleep
29
from typing import Optional
30
31
from websockets.legacy.client import WebSocketClientProtocol
32
33
from pincer import __package__
1 ignored issue
show
Bug Best Practice introduced by
This seems to re-define the built-in __package__.

It is generally discouraged to redefine built-ins as this makes code very hard to read.

Loading history...
34
from pincer.core.dispatch import GatewayDispatch
35
from pincer.exceptions import HeartbeatError
36
37
38
log = logging.getLogger(__package__)
39
40
41
class Heartbeat:
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
42
    __heartbeat: float = 0
43
    __sequence: Optional[int] = None
44
45
    @staticmethod
46
    async def __send(socket: WebSocketClientProtocol):
47
        """
48
        Sends a heartbeat to the API gateway.
49
        """
50
        log.debug(f"Sending heartbeat (seq: {Heartbeat.__sequence})")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
51
        await socket.send(str(GatewayDispatch(1, Heartbeat.__sequence)))
52
53
    @staticmethod
54
    def get() -> float:
55
        """
56
        Get the current heartbeat.
57
58
        :return:
59
            The current heartbeat of the client.
60
            Default is 0 (client has not initialized the heartbeat yet.)
61
62
        """
63
        return Heartbeat.__heartbeat
64
65
    @staticmethod
66
    async def handle_hello(
67
        socket: WebSocketClientProtocol,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
68
        payload: GatewayDispatch
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
69
    ):
70
        """
71
        Handshake between the discord API and the client.
72
        Retrieve the heartbeat for maintaining a connection.
73
        """
74
        log.debug("Handling initial discord hello websocket message.")
75
        Heartbeat.__heartbeat = payload.data.get("heartbeat_interval")
76
77
        if not Heartbeat.__heartbeat:
78
            log.error(
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
79
                "No `heartbeat_interval` is present. Has the API changed? "
80
                f"(payload: {payload})"
81
            )
82
83
            raise HeartbeatError(
84
                "Discord hello is missing `heartbeat_interval` in payload."
85
                "Because of this the client can not maintain a connection. "
86
                "Check logging for more information."
87
            )
88
89
        Heartbeat.__heartbeat /= 1000
90
91
        log.debug(
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
92
            f"Maintaining a connection with heartbeat: {Heartbeat.__heartbeat}"
93
        )
94
95
        if Heartbeat.__sequence:
96
            await socket.send(
97
                str(
98
                    GatewayDispatch(
99
                        6,
100
                        Heartbeat.__sequence,
101
                        seq=Heartbeat.__sequence
102
                    )
103
                )
104
            )
105
106
        else:
107
            await Heartbeat.__send(socket)
108
109
    @staticmethod
110
    async def handle_heartbeat(socket: WebSocketClientProtocol, _):
111
        """
112
        Handles a heartbeat, which means that it rests and then sends a new
113
        heartbeat.
114
        """
115
116
        logging.debug(f"Resting heart for {Heartbeat.__heartbeat}s")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
117
        await sleep(Heartbeat.__heartbeat)
118
        await Heartbeat.__send(socket)
119
120
    @staticmethod
121
    def update_sequence(seq: int):
122
        """
123
        Update the heartbeat sequence.
124
125
        :param seq:
126
            The new heartbeat sequence to be updated with.
127
        """
128
        log.debug("Updating heartbeat sequence...")
129
        Heartbeat.__sequence = seq
130
131
132
handle_hello = Heartbeat.handle_hello
133
handle_heartbeat = Heartbeat.handle_heartbeat
134
update_sequence = Heartbeat.update_sequence
135
136
__all__ = (handle_hello, handle_heartbeat, update_sequence)
0 ignored issues
show
introduced by
Invalid object 'handle_hello' in __all__, must contain only strings
Loading history...
introduced by
Invalid object 'handle_heartbeat' in __all__, must contain only strings
Loading history...
introduced by
Invalid object 'update_sequence' in __all__, must contain only strings
Loading history...
137