lightstreamer_client/subscription_listener.rs
1use crate::item_update::ItemUpdate;
2
3/// Interface to be implemented to listen to Subscription events comprehending notifications
4/// of subscription/unsubscription, updates, errors and others.
5///
6/// Events for these listeners are dispatched by a different thread than the one that generates them.
7/// This means that, upon reception of an event, it is possible that the internal state of the client
8/// has changed. On the other hand, all the notifications for a single LightstreamerClient,
9/// including notifications to ClientListener, SubscriptionListener and ClientMessageListener
10/// will be dispatched by the same thread.
11pub trait SubscriptionListener: Send {
12 /// Event handler that is called by Lightstreamer each time a request to clear the snapshot
13 /// pertaining to an item in the Subscription has been received from the Server.
14 /// More precisely, this kind of request can occur in two cases:
15 ///
16 /// - For an item delivered in COMMAND mode, to notify that the state of the item becomes empty;
17 /// this is equivalent to receiving an update carrying a DELETE command once for each key
18 /// that is currently active.
19 ///
20 /// - For an item delivered in DISTINCT mode, to notify that all the previous updates received
21 /// for the item should be considered as obsolete; hence, if the listener were showing a list
22 /// of recent updates for the item, it should clear the list in order to keep a coherent view.
23 ///
24 /// Note that, if the involved Subscription has a two-level behavior enabled
25 /// (see `Subscription::set_command_second_level_fields()` and
26 /// `Subscription::set_command_second_level_field_schema()`), the notification refers to the
27 /// first-level item (which is in COMMAND mode). This kind of notification is not possible
28 /// for second-level items (which are in MERGE mode).
29 ///
30 /// # Parameters
31 ///
32 /// - `item_name`: name of the involved item. If the Subscription was initialized using an
33 /// "Item Group" then a `None` value is supplied.
34 /// - `item_pos`: 1-based position of the item within the "Item List" or "Item Group".
35 fn on_clear_snapshot(&mut self, _item_name: Option<&str>, _item_pos: usize) {
36 // Default implementation does nothing.
37 unimplemented!("Implement on_clear_snapshot method for SubscriptionListener.");
38 }
39
40 /// Event handler that is called by Lightstreamer to notify that, due to internal resource
41 /// limitations, Lightstreamer Server dropped one or more updates for an item that was
42 /// subscribed to as a second-level subscription. Such notifications are sent only if the
43 /// Subscription was configured in unfiltered mode (second-level items are always in "MERGE"
44 /// mode and inherit the frequency configuration from the first-level Subscription).
45 ///
46 /// By implementing this method it is possible to perform recovery actions.
47 ///
48 /// # Parameters
49 ///
50 /// - `lost_updates`: The number of consecutive updates dropped for the item.
51 /// - `key`: The value of the key that identifies the second-level item.
52 ///
53 /// # See also
54 ///
55 /// - `Subscription::set_requested_max_frequency()`
56 /// - `Subscription::set_command_second_level_fields()`
57 /// - `Subscription::set_command_second_level_field_schema()`
58 fn on_command_second_level_item_lost_updates(&mut self, _lost_updates: u32, _key: &str) {
59 // Default implementation does nothing.
60 unimplemented!(
61 "Implement on_command_second_level_item_lost_updates method for SubscriptionListener."
62 );
63 }
64
65 /// Event handler that is called when the Server notifies an error on a second-level subscription.
66 ///
67 /// By implementing this method it is possible to perform recovery actions.
68 ///
69 /// # Parameters
70 ///
71 /// - `code`: The error code sent by the Server. It can be one of the following:
72 /// - 14 - the key value is not a valid name for the Item to be subscribed; only in this case,
73 /// the error is detected directly by the library before issuing the actual request to the Server
74 /// - 17 - bad Data Adapter name or default Data Adapter not defined for the current Adapter Set
75 /// - 21 - bad Group name
76 /// - 22 - bad Group name for this Schema
77 /// - 23 - bad Schema name
78 /// - 24 - mode not allowed for an Item
79 /// - 26 - unfiltered dispatching not allowed for an Item, because a frequency limit is associated to the item
80 /// - 27 - unfiltered dispatching not supported for an Item, because a frequency prefiltering is applied for the item
81 /// - 28 - unfiltered dispatching is not allowed by the current license terms (for special licenses only)
82 /// - 66 - an unexpected exception was thrown by the Metadata Adapter while authorizing the connection
83 /// - 68 - the Server could not fulfill the request because of an internal error.
84 /// - `<= 0` - the Metadata Adapter has refused the subscription or unsubscription request;
85 /// the code value is dependent on the specific Metadata Adapter implementation
86 /// - `message`: The description of the error sent by the Server; it can be `None`.
87 /// - `key`: The value of the key that identifies the second-level item.
88 ///
89 /// # See also
90 ///
91 /// - `ConnectionDetails::set_adapter_set()`
92 /// - `Subscription::set_command_second_level_fields()`
93 /// - `Subscription::set_command_second_level_field_schema()`
94 fn on_command_second_level_subscription_error(
95 &mut self,
96 _code: i32,
97 _message: Option<&str>,
98 _key: &str,
99 ) {
100 // Default implementation does nothing.
101 unimplemented!(
102 "Implement on_command_second_level_subscription_error method for SubscriptionListener."
103 );
104 }
105
106 /// Event handler that is called by Lightstreamer to notify that all snapshot events for an item
107 /// in the Subscription have been received, so that real time events are now going to be received.
108 /// The received snapshot could be empty. Such notifications are sent only if the items are delivered
109 /// in DISTINCT or COMMAND subscription mode and snapshot information was indeed requested for the items.
110 /// By implementing this method it is possible to perform actions which require that all the initial
111 /// values have been received.
112 ///
113 /// Note that, if the involved Subscription has a two-level behavior enabled
114 /// (see `Subscription::set_command_second_level_fields()` and
115 /// `Subscription::set_command_second_level_field_schema()`), the notification refers to the
116 /// first-level item (which is in COMMAND mode). Snapshot-related updates for the second-level
117 /// items (which are in MERGE mode) can be received both before and after this notification.
118 ///
119 /// # Parameters
120 ///
121 /// - `item_name`: name of the involved item. If the Subscription was initialized using an
122 /// "Item Group" then a `None` value is supplied.
123 /// - `item_pos`: 1-based position of the item within the "Item List" or "Item Group".
124 ///
125 /// # See also
126 ///
127 /// - `Subscription::set_requested_snapshot()`
128 /// - `ItemUpdate::is_snapshot()`
129 fn on_end_of_snapshot(&mut self, _item_name: Option<&str>, _item_pos: usize) {
130 // Default implementation does nothing.
131 unimplemented!("Implement on_end_of_snapshot method for SubscriptionListener.");
132 }
133
134 /// Event handler that is called by Lightstreamer to notify that, due to internal resource
135 /// limitations, Lightstreamer Server dropped one or more updates for an item in the Subscription.
136 /// Such notifications are sent only if the items are delivered in an unfiltered mode; this occurs if the subscription mode is:
137 ///
138 /// - RAW
139 /// - MERGE or DISTINCT, with unfiltered dispatching specified
140 /// - COMMAND, with unfiltered dispatching specified
141 /// - COMMAND, without unfiltered dispatching specified (in this case, notifications apply to ADD and DELETE events only)
142 ///
143 /// By implementing this method it is possible to perform recovery actions.
144 ///
145 /// # Parameters
146 ///
147 /// - `item_name`: name of the involved item. If the Subscription was initialized using an
148 /// "Item Group" then a `None` value is supplied.
149 /// - `item_pos`: 1-based position of the item within the "Item List" or "Item Group".
150 /// - `lost_updates`: The number of consecutive updates dropped for the item.
151 ///
152 /// # See also
153 ///
154 /// - `Subscription::set_requested_max_frequency()`
155 fn on_item_lost_updates(
156 &mut self,
157 _item_name: Option<&str>,
158 _item_pos: usize,
159 _lost_updates: u32,
160 ) {
161 // Default implementation does nothing.
162 unimplemented!("Implement on_item_lost_updates method for SubscriptionListener.");
163 }
164
165 /// Event handler that is called by Lightstreamer each time an update pertaining to an item
166 /// in the Subscription has been received from the Server.
167 ///
168 /// # Parameters
169 ///
170 /// - `update`: a value object containing the updated values for all the fields, together with
171 /// meta-information about the update itself and some helper methods that can be used to
172 /// iterate through all or new values.
173 fn on_item_update(&self, _update: &ItemUpdate) {
174 // Default implementation does nothing.
175 unimplemented!("Implement on_item_update method for SubscriptionListener.");
176 }
177
178 /// Event handler that receives a notification when the `SubscriptionListener` instance is
179 /// removed from a `Subscription` through `Subscription::remove_listener()`. This is the last
180 /// event to be fired on the listener.
181 fn on_listen_end(&mut self) {
182 // Default implementation does nothing.
183 }
184
185 /// Event handler that receives a notification when the `SubscriptionListener` instance is
186 /// added to a `Subscription` through `Subscription::add_listener()`. This is the first event
187 /// to be fired on the listener.
188 fn on_listen_start(&mut self) {
189 // Default implementation does nothing.
190 }
191
192 /// Event handler that is called by Lightstreamer to notify the client with the real maximum
193 /// update frequency of the Subscription. It is called immediately after the Subscription is
194 /// established and in response to a requested change (see `Subscription::set_requested_max_frequency()`).
195 /// Since the frequency limit is applied on an item basis and a Subscription can involve multiple
196 /// items, this is actually the maximum frequency among all items. For Subscriptions with two-level
197 /// behavior (see `Subscription::set_command_second_level_fields()` and
198 /// `Subscription::set_command_second_level_field_schema()`), the reported frequency limit applies
199 /// to both first-level and second-level items.
200 ///
201 /// The value may differ from the requested one because of restrictions operated on the server side,
202 /// but also because of number rounding.
203 ///
204 /// Note that a maximum update frequency (that is, a non-unlimited one) may be applied by the Server
205 /// even when the subscription mode is RAW or the Subscription was done with unfiltered dispatching.
206 ///
207 /// # Parameters
208 ///
209 /// - `frequency`: A decimal number, representing the maximum frequency applied by the Server
210 /// (expressed in updates per second), or the string "unlimited". A `None` value is possible in
211 /// rare cases, when the frequency can no longer be determined.
212 fn on_real_max_frequency(&mut self, _frequency: Option<f64>) {
213 // Default implementation does nothing.
214 unimplemented!("Implement on_real_max_frequency method for SubscriptionListener.");
215 }
216
217 /// Event handler that is called by Lightstreamer to notify that a Subscription has been successfully
218 /// subscribed to through the Server. This can happen multiple times in the life of a Subscription
219 /// instance, in case the Subscription is performed multiple times through `LightstreamerClient::unsubscribe()`
220 /// and `LightstreamerClient::subscribe()`. This can also happen multiple times in case of automatic
221 /// recovery after a connection restart.
222 ///
223 /// This notification is always issued before the other ones related to the same subscription.
224 /// It invalidates all data that has been received previously.
225 ///
226 /// Note that two consecutive calls to this method are not possible, as before a second
227 /// `on_subscription` event is fired an `on_unsubscription()` event is eventually fired.
228 ///
229 /// If the involved Subscription has a two-level behavior enabled
230 /// (see `Subscription::set_command_second_level_fields()` and
231 /// `Subscription::set_command_second_level_field_schema()`), second-level subscriptions are not notified.
232 fn on_subscription(&mut self) {
233 // Default implementation does nothing.
234 }
235
236 /// Event handler that is called when the Server notifies an error on a Subscription.
237 /// By implementing this method it is possible to perform recovery actions.
238 ///
239 /// Note that, in order to perform a new subscription attempt, `LightstreamerClient::unsubscribe()`
240 /// and `LightstreamerClient::subscribe()` should be issued again, even if no change to the
241 /// Subscription attributes has been applied.
242 ///
243 /// # Parameters
244 ///
245 /// - `code`: The error code sent by the Server. It can be one of the following:
246 /// - 15 - "key" field not specified in the schema for a COMMAND mode subscription
247 /// - 16 - "command" field not specified in the schema for a COMMAND mode subscription
248 /// - 17 - bad Data Adapter name or default Data Adapter not defined for the current Adapter Set
249 /// - 21 - bad Group name
250 /// - 22 - bad Group name for this Schema
251 /// - 23 - bad Schema name
252 /// - 24 - mode not allowed for an Item
253 /// - 25 - bad Selector name
254 /// - 26 - unfiltered dispatching not allowed for an Item, because a frequency limit is associated to the item
255 /// - 27 - unfiltered dispatching not supported for an Item, because a frequency prefiltering is applied for the item
256 /// - 28 - unfiltered dispatching is not allowed by the current license terms (for special licenses only)
257 /// - 29 - RAW mode is not allowed by the current license terms (for special licenses only)
258 /// - 30 - subscriptions are not allowed by the current license terms (for special licenses only)
259 /// - 66 - an unexpected exception was thrown by the Metadata Adapter while authorizing the connection
260 /// - 68 - the Server could not fulfill the request because of an internal error.
261 /// - `<= 0` - the Metadata Adapter has refused the subscription or unsubscription request;
262 /// the code value is dependent on the specific Metadata Adapter implementation
263 /// - `message`: The description of the error sent by the Server; it can be `None`.
264 ///
265 /// # See also
266 ///
267 /// - `ConnectionDetails::set_adapter_set()`
268 fn on_subscription_error(&mut self, _code: i32, _message: Option<&str>) {
269 // Default implementation does nothing.
270 unimplemented!("Implement on_subscription_error method for SubscriptionListener.");
271 }
272
273 /// Event handler that is called by Lightstreamer to notify that a Subscription has been successfully
274 /// unsubscribed from. This can happen multiple times in the life of a Subscription instance, in case
275 /// the Subscription is performed multiple times through `LightstreamerClient::unsubscribe()` and
276 /// `LightstreamerClient::subscribe()`. This can also happen multiple times in case of automatic
277 /// recovery after a connection restart.
278 ///
279 /// After this notification no more events can be received until a new `on_subscription` event.
280 ///
281 /// Note that two consecutive calls to this method are not possible, as before a second
282 /// `on_unsubscription` event is fired an `on_subscription()` event is eventually fired.
283 ///
284 /// If the involved Subscription has a two-level behavior enabled
285 /// (see `Subscription::set_command_second_level_fields()` and
286 /// `Subscription::set_command_second_level_field_schema()`), second-level unsubscriptions are not notified.
287 fn on_unsubscription(&mut self) {
288 // Default implementation does nothing.
289 }
290}