Skip to content

Commit 95b7bce

Browse files
committed
Confirm WebSocket subscription update and removal responses (#106)
1 parent 7306b08 commit 95b7bce

2 files changed

Lines changed: 577 additions & 13 deletions

File tree

‎ringcentral/websocket/web_socket_subscription.py‎

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,18 @@ def __init__(self, web_socket_client):
1515
self._event_filters = []
1616
self._subscription = None
1717
self._pending_creation_message_id = None
18+
self._pending_update_message_id = None
19+
self._pending_update_filters = None
20+
self._pending_removal_message_id = None
1821
self._receive_message_listener_attached = False
1922

23+
def _operation_pending(self):
24+
return (
25+
self._pending_creation_message_id is not None
26+
or self._pending_update_message_id is not None
27+
or self._pending_removal_message_id is not None
28+
)
29+
2030
def on_message(self, message):
2131
message_json = json.loads(message)
2232
if(
@@ -32,6 +42,36 @@ def on_message(self, message):
3242
else:
3343
error = Exception(f"WebSocket subscription creation failed with status {status}")
3444
self._web_socket_client.trigger(WebSocketEvents.createSubscriptionError, error)
45+
elif(
46+
self._pending_update_message_id is not None
47+
and message_json[0].get('messageId') == self._pending_update_message_id
48+
):
49+
status = message_json[0].get('status', 0)
50+
proposed_filters = self._pending_update_filters
51+
self._pending_update_message_id = None
52+
self._pending_update_filters = None
53+
if 200 <= status < 300:
54+
self.set_subscription(message_json)
55+
self.set_events(proposed_filters)
56+
self._web_socket_client.trigger(WebSocketEvents.subscriptionUpdated, self)
57+
else:
58+
error = Exception(f"WebSocket subscription update failed with status {status}")
59+
self._web_socket_client.trigger(WebSocketEvents.updateSubscriptionError, error)
60+
elif(
61+
self._pending_removal_message_id is not None
62+
and message_json[0].get('messageId') == self._pending_removal_message_id
63+
):
64+
status = message_json[0].get('status', 0)
65+
self._pending_removal_message_id = None
66+
if 200 <= status < 300:
67+
if self._receive_message_listener_attached:
68+
self._web_socket_client.off(WebSocketEvents.receiveMessage, self.on_message)
69+
self._receive_message_listener_attached = False
70+
self.reset()
71+
self._web_socket_client.trigger(WebSocketEvents.subscriptionRemoved)
72+
else:
73+
error = Exception(f"WebSocket subscription removal failed with status {status}")
74+
self._web_socket_client.trigger(WebSocketEvents.removeSubscriptionError, error)
3575
elif message_json[0].get('type') == 'ServerNotification':
3676
self._web_socket_client.trigger(WebSocketEvents.receiveSubscriptionNotification, message_json)
3777

@@ -90,15 +130,18 @@ async def subscribe(self, events=None):
90130
raise
91131

92132
async def update(self, events=None):
93-
if events:
94-
self.set_events(events)
133+
if self._operation_pending():
134+
raise Exception("Subscription update is already in progress")
95135

96-
if not self._event_filters or len(self._event_filters) == 0:
136+
proposed_filters = events if events else self._event_filters
137+
if not proposed_filters or len(proposed_filters) == 0:
97138
raise Exception("Events are undefined")
98139

99140
try:
100141
subscriptionId = self._subscription[1]["id"]
101142
messageId = str(uuid.uuid4())
143+
self._pending_update_message_id = messageId
144+
self._pending_update_filters = proposed_filters
102145
requestBodyJson = [
103146
{
104147
"type": "ClientRequest",
@@ -107,25 +150,29 @@ async def update(self, events=None):
107150
"path": f"/restapi/v1.0/subscription/{subscriptionId}",
108151
},
109152
{
110-
"eventFilters": self._event_filters,
153+
"eventFilters": proposed_filters,
111154
"deliveryMode": {"transportType": "WebSocket"},
112155
},
113156
]
114157
await self._web_socket_client.send_message(requestBodyJson)
115-
self._web_socket_client.trigger(WebSocketEvents.subscriptionUpdated, self)
116158

117159
except Exception as e:
118-
self.reset()
160+
self._pending_update_message_id = None
161+
self._pending_update_filters = None
119162
print(e)
120163
raise
121164

122165
async def remove(self):
166+
if self._operation_pending():
167+
raise Exception("Subscription removal is already in progress")
168+
123169
subscriptionId = self._subscription[1]["id"]
124170
if not subscriptionId:
125171
raise Exception("Missing subscriptionId")
126172

127173
try:
128174
messageId = str(uuid.uuid4())
175+
self._pending_removal_message_id = messageId
129176
requestBodyJson = [
130177
{
131178
"type": "ClientRequest",
@@ -136,15 +183,9 @@ async def remove(self):
136183
]
137184

138185
await self._web_socket_client.send_message(requestBodyJson)
139-
if self._receive_message_listener_attached:
140-
self._web_socket_client.off(WebSocketEvents.receiveMessage, self.on_message)
141-
self._receive_message_listener_attached = False
142-
self._web_socket_client.trigger(WebSocketEvents.subscriptionRemoved)
143-
144-
self.reset()
145186

146187
except Exception as e:
147-
self.reset()
188+
self._pending_removal_message_id = None
148189
print(e)
149190
raise
150191

0 commit comments

Comments
 (0)