1use anyhow::Result;
2use futures_util::FutureExt;
3use parking_lot::Mutex as SyncMutex;
4use scc::{hash_map::Entry as SccEntry, HashMap as SccHashMap};
5use serde_json::Value;
6use std::fmt::{Debug, Display};
7use std::ops::Deref;
8use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
9use std::sync::{Arc, Weak};
10use std::time::Duration;
11use tokio::sync::{broadcast, oneshot, watch, Mutex};
12
13use crate::{
14 backoff::Backoff,
15 drivers::*,
16 protocol::{query::ActorQuery, *},
17 remote_manager::RemoteManager,
18 EncodingKind, TransportKind,
19};
20use tracing::debug;
21
22type RpcResponse = Result<to_client::ActionResponse, to_client::Error>;
23type EventCallback = dyn Fn(Event) + Send + Sync;
24type VoidCallback = dyn Fn() + Send + Sync;
25type ErrorCallback = dyn Fn(&str) + Send + Sync;
26type StatusCallback = dyn Fn(ConnectionStatus) + Send + Sync;
27
28#[derive(Debug, Clone)]
29pub struct Event {
30 pub name: String,
31 pub args: Vec<Value>,
32 pub raw_args: Vec<u8>,
33}
34
35struct EventSubscription {
36 id: u64,
37 callback: Box<EventCallback>,
38}
39
40#[derive(Clone)]
41pub struct SubscriptionHandle {
42 inner: Arc<SubscriptionHandleInner>,
43}
44
45struct SubscriptionHandleInner {
46 conn: Weak<ActorConnectionInner>,
47 event_name: String,
48 id: u64,
49 active: AtomicBool,
50}
51
52impl SubscriptionHandle {
53 fn new(conn: &Arc<ActorConnectionInner>, event_name: String, id: u64) -> Self {
54 Self {
55 inner: Arc::new(SubscriptionHandleInner {
56 conn: Arc::downgrade(conn),
57 event_name,
58 id,
59 active: AtomicBool::new(true),
60 }),
61 }
62 }
63
64 pub async fn unsubscribe(&self) {
65 if !self.inner.active.swap(false, Ordering::SeqCst) {
66 return;
67 }
68
69 let Some(conn) = self.inner.conn.upgrade() else {
70 return;
71 };
72
73 conn.remove_event_subscription(&self.inner.event_name, self.inner.id)
74 .await;
75 }
76}
77
78struct SendMsgOpts {
79 ephemeral: bool,
80}
81
82impl Default for SendMsgOpts {
83 fn default() -> Self {
84 Self { ephemeral: false }
85 }
86}
87
88type WatchPair = (watch::Sender<bool>, watch::Receiver<bool>);
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq)]
91pub enum ConnectionStatus {
92 Idle,
93 Connecting,
94 Connected,
95 Disconnected,
96}
97
98pub type ActorConnection = Arc<ActorConnectionInner>;
99
100struct ConnectionAttempt {
101 did_open: bool,
102 task_end_reason: DriverStopReason,
103}
104
105pub struct ActorConnectionInner {
106 remote_manager: RemoteManager,
107 transport_kind: TransportKind,
108 encoding_kind: EncodingKind,
109 query: ActorQuery,
110 parameters: Option<Value>,
111
112 driver: Mutex<Option<DriverHandle>>,
113 msg_queue: Mutex<Vec<Arc<to_server::ToServer>>>,
114
115 rpc_counter: AtomicU64,
116 event_subscription_counter: AtomicU64,
117 in_flight_rpcs: SccHashMap<u64, oneshot::Sender<RpcResponse>>,
118
119 event_subscriptions: SccHashMap<String, Vec<Arc<EventSubscription>>>,
120 on_open_callbacks: Mutex<Vec<Box<VoidCallback>>>,
121 on_close_callbacks: Mutex<Vec<Box<VoidCallback>>>,
122 on_error_callbacks: Mutex<Vec<Box<ErrorCallback>>>,
123 on_status_change_callbacks: Mutex<Vec<Box<StatusCallback>>>,
124
125 actor_id: Mutex<Option<String>>,
127 connection_id: Mutex<Option<String>>,
128 connection_token: Mutex<Option<String>>,
129
130 dc_watch: WatchPair,
131 stop_error: Mutex<Option<StopError>>,
132 status_watch: (
133 watch::Sender<ConnectionStatus>,
134 watch::Receiver<ConnectionStatus>,
135 ),
136 disconnection_rx: Mutex<Option<oneshot::Receiver<()>>>,
137}
138
139impl ActorConnectionInner {
140 pub(crate) fn new(
141 remote_manager: RemoteManager,
142 query: ActorQuery,
143 transport_kind: TransportKind,
144 encoding_kind: EncodingKind,
145 parameters: Option<Value>,
146 ) -> ActorConnection {
147 Arc::new(Self {
148 remote_manager,
149 transport_kind,
150 encoding_kind,
151 query,
152 parameters,
153 driver: Mutex::new(None),
154 msg_queue: Mutex::new(Vec::new()),
155 rpc_counter: AtomicU64::new(0),
156 event_subscription_counter: AtomicU64::new(0),
157 in_flight_rpcs: SccHashMap::new(),
158 event_subscriptions: SccHashMap::new(),
159 on_open_callbacks: Mutex::new(Vec::new()),
160 on_close_callbacks: Mutex::new(Vec::new()),
161 on_error_callbacks: Mutex::new(Vec::new()),
162 on_status_change_callbacks: Mutex::new(Vec::new()),
163 actor_id: Mutex::new(None),
164 connection_id: Mutex::new(None),
165 connection_token: Mutex::new(None),
166 dc_watch: watch::channel(false),
167 stop_error: Mutex::new(None),
168 status_watch: watch::channel(ConnectionStatus::Idle),
169 disconnection_rx: Mutex::new(None),
170 })
171 }
172
173 fn is_disconnecting(self: &Arc<Self>) -> bool {
174 *self.dc_watch.1.borrow() == true
175 }
176
177 async fn try_connect(self: &Arc<Self>) -> ConnectionAttempt {
178 self.set_status(ConnectionStatus::Connecting).await;
179
180 let conn_id = self.connection_id.lock().await.clone();
182 let conn_token = self.connection_token.lock().await.clone();
183
184 let (driver, mut recver, task) = match connect_driver(
185 self.transport_kind,
186 DriverConnectArgs {
187 remote_manager: self.remote_manager.clone(),
188 query: self.query.clone(),
189 encoding_kind: self.encoding_kind,
190 parameters: self.parameters.clone(),
191 conn_id,
192 conn_token,
193 },
194 )
195 .await
196 {
197 Ok(value) => value,
198 Err(error) => {
199 let message = error.to_string();
200 self.emit_error(&message).await;
201 self.set_status(ConnectionStatus::Disconnected).await;
202 return ConnectionAttempt {
203 did_open: false,
204 task_end_reason: DriverStopReason::TaskError,
205 };
206 }
207 };
208
209 {
210 let mut my_driver = self.driver.lock().await;
211 *my_driver = Some(driver);
212 }
213
214 let mut task_end_reason = task.map(|res| match res {
215 Ok(a) => a,
216 Err(task_err) => {
217 if task_err.is_cancelled() {
218 debug!("Connection task was cancelled");
219 DriverStopReason::UserAborted
220 } else {
221 DriverStopReason::TaskError
222 }
223 }
224 });
225
226 let mut did_connection_open = false;
227
228 let task_end_reason = loop {
230 tokio::select! {
231 reason = &mut task_end_reason => {
232 debug!("Connection closed: {:?}", reason);
233
234 break reason;
235 },
236 msg = recver.recv() => {
237 let Some(msg) = msg else {
239 continue;
241 };
242
243 if let to_client::ToClientBody::Init(_) = &msg.body {
244 did_connection_open = true;
245 }
246
247 self.on_message(msg).await;
248 }
249 }
250 };
251
252 'destroy_driver: {
253 debug!("Destroying driver");
254 let mut d_guard = self.driver.lock().await;
255 let Some(d) = d_guard.take() else {
256 break 'destroy_driver;
259 };
260
261 d.disconnect();
262 }
263
264 self.set_status(ConnectionStatus::Disconnected).await;
265 self.emit_close().await;
266
267 ConnectionAttempt {
268 did_open: did_connection_open,
269 task_end_reason,
270 }
271 }
272
273 async fn handle_open(self: &Arc<Self>, init: &to_client::Init) {
274 debug!("Connected to server: {:?}", init);
275
276 *self.actor_id.lock().await = Some(init.actor_id.clone());
278 *self.connection_id.lock().await = Some(init.connection_id.clone());
279 *self.connection_token.lock().await = init.connection_token.clone();
280 self.set_status(ConnectionStatus::Connected).await;
281 self.emit_open().await;
282
283 let mut event_names = Vec::new();
284 self.event_subscriptions
285 .iter_async(|event_name, _| {
286 event_names.push(event_name.clone());
287 true
288 })
289 .await;
290 for event_name in event_names {
291 self.send_subscription(event_name.clone(), true).await;
292 }
293
294 for msg in self.msg_queue.lock().await.drain(..) {
296 self.send_msg(msg, SendMsgOpts::default()).await;
299 }
300 }
301
302 async fn on_message(self: &Arc<Self>, msg: Arc<to_client::ToClient>) {
303 let body = &msg.body;
304
305 match body {
306 to_client::ToClientBody::Init(init) => {
307 self.handle_open(init).await;
308 }
309 to_client::ToClientBody::ActionResponse(ar) => {
310 let id = ar.id;
311 let Some((_, tx)) = self.in_flight_rpcs.remove_async(&id).await else {
312 debug!("Unexpected response: rpc id not found");
313 return;
314 };
315 if let Err(e) = tx.send(Ok(ar.clone())) {
316 debug!("{:?}", e);
317 return;
318 }
319 }
320 to_client::ToClientBody::Event(ev) => {
321 let args = decode_event_args(&ev.args);
322
323 let callbacks = {
324 self.event_subscriptions
325 .read_async(&ev.name, |_, listeners| listeners.clone())
326 .await
327 .unwrap_or_default()
328 };
329 let event = Event {
330 name: ev.name.clone(),
331 args,
332 raw_args: ev.args.clone(),
333 };
334 for subscription in callbacks {
335 (subscription.callback)(event.clone());
336 }
337 }
338 to_client::ToClientBody::Error(e) => {
339 if let Some(action_id) = e.action_id {
340 let Some((_, tx)) = self.in_flight_rpcs.remove_async(&action_id).await else {
341 debug!("Unexpected response: rpc id not found");
342 return;
343 };
344 if let Err(e) = tx.send(Err(e.clone())) {
345 debug!("{:?}", e);
346 return;
347 }
348
349 return;
350 }
351
352 debug!("Connection error: {} - {}", e.code, e.message);
353 self.emit_error(&e.message).await;
354 }
355 }
356 }
357
358 async fn set_status(self: &Arc<Self>, status: ConnectionStatus) {
359 if *self.status_watch.1.borrow() == status {
360 return;
361 }
362 self.status_watch.0.send(status).ok();
363 for callback in self.on_status_change_callbacks.lock().await.iter() {
364 callback(status);
365 }
366 }
367
368 async fn emit_open(self: &Arc<Self>) {
369 for callback in self.on_open_callbacks.lock().await.iter() {
370 callback();
371 }
372 }
373
374 async fn emit_close(self: &Arc<Self>) {
375 for callback in self.on_close_callbacks.lock().await.iter() {
376 callback();
377 }
378 }
379
380 async fn emit_error(self: &Arc<Self>, message: &str) {
381 for callback in self.on_error_callbacks.lock().await.iter() {
382 callback(message);
383 }
384 }
385
386 async fn send_msg(self: &Arc<Self>, msg: Arc<to_server::ToServer>, opts: SendMsgOpts) {
387 let guard = self.driver.lock().await;
388
389 'send_immediately: {
390 let Some(driver) = guard.deref() else {
391 break 'send_immediately;
392 };
393
394 let Ok(_) = driver.send(msg.clone()).await else {
395 break 'send_immediately;
396 };
397
398 return;
399 }
400
401 if opts.ephemeral == false {
403 self.msg_queue.lock().await.push(msg.clone());
404 }
405
406 return;
407 }
408
409 pub async fn action(self: &Arc<Self>, method: &str, params: Vec<Value>) -> Result<Value> {
410 if let Some(stop_error) = self.stop_error.lock().await.as_ref() {
411 return Err(stop_error.to_rpc_error());
412 }
413 let id: u64 = self.rpc_counter.fetch_add(1, Ordering::SeqCst);
414
415 let (tx, rx) = oneshot::channel();
416 if self.in_flight_rpcs.insert_async(id, tx).await.is_err() {
417 return Err(anyhow::anyhow!("duplicate rpc id"));
418 }
419 if let Some(stop_error) = self.stop_error.lock().await.as_ref() {
422 self.in_flight_rpcs.remove_async(&id).await;
423 return Err(stop_error.to_rpc_error());
424 }
425
426 let args_cbor = serde_cbor::to_vec(¶ms)?;
428
429 self.send_msg(
430 Arc::new(to_server::ToServer {
431 body: to_server::ToServerBody::ActionRequest(to_server::ActionRequest {
432 id,
433 name: method.to_string(),
434 args: args_cbor,
435 }),
436 }),
437 SendMsgOpts::default(),
438 )
439 .await;
440
441 let Ok(res) = rx.await else {
442 if let Some(stop_error) = self.stop_error.lock().await.as_ref() {
443 return Err(stop_error.to_rpc_error());
444 }
445 return Err(anyhow::anyhow!("Socket closed during rpc"));
446 };
447
448 match res {
449 Ok(ok) => {
450 let output: Value = serde_cbor::from_slice(&ok.output)?;
452 Ok(output)
453 }
454 Err(err) => {
455 let metadata = if let Some(md) = &err.metadata {
456 match serde_cbor::from_slice::<Value>(md) {
457 Ok(v) => v,
458 Err(_) => Value::Null,
459 }
460 } else {
461 Value::Null
462 };
463
464 Err(anyhow::anyhow!(
465 "RPC Error({}/{}): {}, {:#}",
466 err.group,
467 err.code,
468 err.message,
469 metadata
470 ))
471 }
472 }
473 }
474
475 async fn send_subscription(self: &Arc<Self>, event_name: String, subscribe: bool) {
476 self.send_msg(
477 Arc::new(to_server::ToServer {
478 body: to_server::ToServerBody::SubscriptionRequest(
479 to_server::SubscriptionRequest {
480 event_name,
481 subscribe,
482 },
483 ),
484 }),
485 SendMsgOpts { ephemeral: true },
486 )
487 .await;
488 }
489
490 async fn add_event_subscription(
491 self: &Arc<Self>,
492 event_name: String,
493 callback: Box<EventCallback>,
494 ) -> SubscriptionHandle {
495 let id = self
496 .event_subscription_counter
497 .fetch_add(1, Ordering::SeqCst);
498 let handle = SubscriptionHandle::new(self, event_name.clone(), id);
499
500 self.insert_event_subscription(event_name, id, callback)
501 .await;
502
503 handle
504 }
505
506 async fn insert_event_subscription(
507 self: &Arc<Self>,
508 event_name: String,
509 id: u64,
510 callback: Box<EventCallback>,
511 ) {
512 let is_new_subscription = {
513 let mut listeners = self
514 .event_subscriptions
515 .entry_async(event_name.clone())
516 .await
517 .or_insert_with(Vec::new);
518 let is_new_subscription = listeners.is_empty();
519
520 listeners.push(Arc::new(EventSubscription { id, callback }));
521
522 is_new_subscription
523 };
524
525 if is_new_subscription {
526 self.send_subscription(event_name, true).await;
527 }
528 }
529
530 async fn remove_event_subscription(self: &Arc<Self>, event_name: &str, id: u64) {
531 let should_unsubscribe = {
532 match self
533 .event_subscriptions
534 .entry_async(event_name.to_string())
535 .await
536 {
537 SccEntry::Occupied(mut entry) => {
538 entry.retain(|subscription| subscription.id != id);
539 if entry.is_empty() {
540 let _ = entry.remove_entry();
541 true
542 } else {
543 false
544 }
545 }
546 SccEntry::Vacant(entry) => {
547 drop(entry);
548 false
549 }
550 }
551 };
552
553 if should_unsubscribe {
554 self.send_subscription(event_name.to_string(), false).await;
555 }
556 }
557
558 pub async fn on_event<F>(self: &Arc<Self>, event_name: &str, callback: F) -> SubscriptionHandle
559 where
560 F: Fn(&Vec<Value>) + Send + Sync + 'static,
561 {
562 self.add_event_subscription(
563 event_name.to_string(),
564 Box::new(move |event| callback(&event.args)),
565 )
566 .await
567 }
568
569 pub async fn on_event_raw<F>(
570 self: &Arc<Self>,
571 event_name: &str,
572 callback: F,
573 ) -> SubscriptionHandle
574 where
575 F: Fn(Event) + Send + Sync + 'static,
576 {
577 self.add_event_subscription(event_name.to_string(), Box::new(callback))
578 .await
579 }
580
581 pub async fn once_event<F>(
582 self: &Arc<Self>,
583 event_name: &str,
584 callback: F,
585 ) -> SubscriptionHandle
586 where
587 F: FnOnce(Event) + Send + 'static,
588 {
589 let id = self
590 .event_subscription_counter
591 .fetch_add(1, Ordering::SeqCst);
592 let handle = SubscriptionHandle::new(self, event_name.to_string(), id);
593 let callback = Arc::new(SyncMutex::new(Some(callback)));
595 let unsubscribe_handle = handle.clone();
596 let fired = Arc::new(AtomicBool::new(false));
597 self.insert_event_subscription(
598 event_name.to_string(),
599 id,
600 Box::new(move |event| {
601 if fired.swap(true, Ordering::SeqCst) {
602 return;
603 }
604
605 let unsubscribe_handle = unsubscribe_handle.clone();
606 tokio::spawn(async move {
607 unsubscribe_handle.unsubscribe().await;
608 });
609
610 let Some(callback) = callback.lock().take() else {
611 return;
612 };
613 callback(event);
614 }),
615 )
616 .await;
617
618 handle
619 }
620
621 pub async fn on_open<F>(self: &Arc<Self>, callback: F)
622 where
623 F: Fn() + Send + Sync + 'static,
624 {
625 self.on_open_callbacks.lock().await.push(Box::new(callback));
626 }
627
628 pub async fn on_close<F>(self: &Arc<Self>, callback: F)
629 where
630 F: Fn() + Send + Sync + 'static,
631 {
632 self.on_close_callbacks
633 .lock()
634 .await
635 .push(Box::new(callback));
636 }
637
638 pub async fn on_error<F>(self: &Arc<Self>, callback: F)
639 where
640 F: Fn(&str) + Send + Sync + 'static,
641 {
642 self.on_error_callbacks
643 .lock()
644 .await
645 .push(Box::new(callback));
646 }
647
648 pub async fn on_status_change<F>(self: &Arc<Self>, callback: F)
649 where
650 F: Fn(ConnectionStatus) + Send + Sync + 'static,
651 {
652 self.on_status_change_callbacks
653 .lock()
654 .await
655 .push(Box::new(callback));
656 }
657
658 pub fn conn_status(self: &Arc<Self>) -> ConnectionStatus {
659 *self.status_watch.1.borrow()
660 }
661
662 pub fn status_receiver(self: &Arc<Self>) -> watch::Receiver<ConnectionStatus> {
663 self.status_watch.1.clone()
664 }
665
666 pub async fn disconnect(self: &Arc<Self>) {
667 if self.is_disconnecting() {
668 return;
670 }
671
672 debug!("Disconnecting from actor conn");
673
674 self.dc_watch.0.send(true).ok();
675 self.set_status(ConnectionStatus::Disconnected).await;
676
677 if let Some(d) = self.driver.lock().await.deref() {
678 d.disconnect();
679 }
680 self.in_flight_rpcs.clear_async().await;
681 self.event_subscriptions.clear_async().await;
682 let Some(rx) = self.disconnection_rx.lock().await.take() else {
683 return;
684 };
685
686 rx.await.ok();
687 }
688
689 pub async fn dispose(self: &Arc<Self>) {
690 self.disconnect().await
691 }
692
693 async fn stop_permanently(self: &Arc<Self>, stop_error: StopError) {
694 let message = stop_error.to_string();
695 *self.stop_error.lock().await = Some(stop_error);
696 self.set_status(ConnectionStatus::Idle).await;
697 self.in_flight_rpcs.clear_async().await;
698 self.emit_error(&message).await;
699 }
700}
701
702#[derive(Debug, Clone)]
703struct StopError {
704 group: String,
705 code: String,
706 reason: String,
707}
708
709impl StopError {
710 fn from_close_reason(reason: &str) -> Self {
711 let group_code = reason.split('#').next().unwrap_or(reason);
712 let (group, code) = group_code.split_once('.').unwrap_or((group_code, ""));
713 Self {
714 group: group.to_owned(),
715 code: code.to_owned(),
716 reason: reason.to_owned(),
717 }
718 }
719
720 fn to_rpc_error(&self) -> anyhow::Error {
721 anyhow::anyhow!(
722 "RPC Error({}/{}): Connection closed: {}",
723 self.group,
724 self.code,
725 self.reason
726 )
727 }
728}
729
730impl Display for StopError {
731 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
732 write!(
733 f,
734 "{}.{}: Connection closed: {}",
735 self.group, self.code, self.reason
736 )
737 }
738}
739
740pub fn start_connection(
741 conn: &Arc<ActorConnectionInner>,
742 mut shutdown_rx: broadcast::Receiver<()>,
743) {
744 let (tx, rx) = oneshot::channel();
745
746 let conn = conn.clone();
747
748 tokio::spawn(async move {
749 {
750 let mut stop_rx = conn.disconnection_rx.lock().await;
751 if stop_rx.is_some() {
752 return;
755 }
756
757 *stop_rx = Some(rx);
758 }
759
760 'keepalive: loop {
761 debug!("Attempting to reconnect");
762 let mut backoff = Backoff::new(Duration::from_secs(1), Duration::from_secs(30));
763 let mut retry_attempt = 0;
764 'retry: loop {
765 retry_attempt += 1;
766 debug!(
767 "Establish conn: attempt={}, timeout={:?}",
768 retry_attempt,
769 backoff.delay()
770 );
771 let attempt = conn.try_connect().await;
772
773 if conn.is_disconnecting() {
774 break 'keepalive;
775 }
776
777 match &attempt.task_end_reason {
778 DriverStopReason::ActorDestroyed { reason } => {
779 conn.stop_permanently(StopError::from_close_reason(reason))
780 .await;
781 break 'keepalive;
782 }
783 DriverStopReason::AuthRefused { reason } => {
786 conn.stop_permanently(StopError::from_close_reason(reason))
787 .await;
788 break 'keepalive;
789 }
790 DriverStopReason::ActorNotFound { reason } => {
791 let stops = match &conn.query {
792 ActorQuery::GetForId { .. } => true,
793 ActorQuery::GetForKey { .. } => !attempt.did_open,
794 ActorQuery::GetOrCreateForKey { .. } | ActorQuery::Create { .. } => {
795 false
796 }
797 };
798 if stops {
799 conn.stop_permanently(StopError::from_close_reason(reason))
800 .await;
801 break 'keepalive;
802 }
803 }
804 DriverStopReason::UserAborted
805 | DriverStopReason::ServerDisconnect
806 | DriverStopReason::ServerError
807 | DriverStopReason::TaskError => {}
808 }
809
810 if attempt.did_open {
811 break 'retry;
812 }
813
814 let mut dc_rx = conn.dc_watch.0.subscribe();
815
816 tokio::select! {
817 _ = backoff.tick() => {},
818 _ = dc_rx.wait_for(|x| *x == true) => {
819 break 'keepalive;
820 }
821 _ = shutdown_rx.recv() => {
822 debug!("Received shutdown signal, stopping connection attempts");
823 break 'keepalive;
824 }
825 }
826 }
827 }
828
829 tx.send(()).ok();
830 conn.disconnection_rx.lock().await.take();
831 });
832}
833
834impl Debug for ActorConnectionInner {
835 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
836 f.debug_struct("ActorConnection")
837 .field("transport_kind", &self.transport_kind)
838 .field("encoding_kind", &self.encoding_kind)
839 .finish()
840 }
841}
842
843fn decode_event_args(raw_args: &[u8]) -> Vec<Value> {
844 match serde_cbor::from_slice::<Vec<Value>>(raw_args) {
845 Ok(args) => args,
846 Err(vector_error) => match serde_cbor::from_slice::<Value>(raw_args) {
847 Ok(Value::Array(args)) => args,
848 Ok(value) => vec![value],
849 Err(value_error) => {
850 debug!(?vector_error, ?value_error, "failed to decode event args");
851 Vec::new()
852 }
853 },
854 }
855}