AccountsDb plugin framework (#20047)
Summary of Changes Create a plugin mechanism in the accounts update path so that accounts data can be streamed out to external data stores (be it Kafka or Postgres). The plugin mechanism allows Data stores of connection strings/credentials to be configured, Accounts with patterns to be streamed PostgreSQL implementation of the streaming for different destination stores to be plugged in. The code comprises 4 major parts: accountsdb-plugin-intf: defines the plugin interface which concrete plugin should implement. accountsdb-plugin-manager: manages the load/unload of plugins and provide interfaces which the validator can notify of accounts update to plugins. accountsdb-plugin-postgres: the concrete plugin implementation for PostgreSQL The validator integrations: updated streamed right after snapshot restore and after account update from transaction processing or other real updates. The plugin is optionally loaded on demand by new validator CLI argument -- there is no impact if the plugin is not loaded.
This commit is contained in:
@ -31,6 +31,7 @@ impl OptimisticallyConfirmedBank {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum BankNotification {
|
||||
OptimisticallyConfirmed(Slot),
|
||||
Frozen(Arc<Bank>),
|
||||
@ -63,7 +64,7 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
bank_forks: Arc<RwLock<BankForks>>,
|
||||
optimistically_confirmed_bank: Arc<RwLock<OptimisticallyConfirmedBank>>,
|
||||
subscriptions: Arc<RpcSubscriptions>,
|
||||
confirmed_bank_subscribers: Option<Arc<RwLock<Vec<Sender<Slot>>>>>,
|
||||
bank_notification_subscribers: Option<Arc<RwLock<Vec<BankNotificationSender>>>>,
|
||||
) -> Self {
|
||||
let exit_ = exit.clone();
|
||||
let mut pending_optimistically_confirmed_banks = HashSet::new();
|
||||
@ -84,7 +85,7 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
&mut pending_optimistically_confirmed_banks,
|
||||
&mut last_notified_confirmed_slot,
|
||||
&mut highest_confirmed_slot,
|
||||
&confirmed_bank_subscribers,
|
||||
&bank_notification_subscribers,
|
||||
) {
|
||||
break;
|
||||
}
|
||||
@ -101,7 +102,7 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
mut pending_optimistically_confirmed_banks: &mut HashSet<Slot>,
|
||||
mut last_notified_confirmed_slot: &mut Slot,
|
||||
mut highest_confirmed_slot: &mut Slot,
|
||||
confirmed_bank_subscribers: &Option<Arc<RwLock<Vec<Sender<Slot>>>>>,
|
||||
bank_notification_subscribers: &Option<Arc<RwLock<Vec<BankNotificationSender>>>>,
|
||||
) -> Result<(), RecvTimeoutError> {
|
||||
let notification = receiver.recv_timeout(Duration::from_secs(1))?;
|
||||
Self::process_notification(
|
||||
@ -112,18 +113,37 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
&mut pending_optimistically_confirmed_banks,
|
||||
&mut last_notified_confirmed_slot,
|
||||
&mut highest_confirmed_slot,
|
||||
confirmed_bank_subscribers,
|
||||
bank_notification_subscribers,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn notify_slot_status(
|
||||
bank_notification_subscribers: &Option<Arc<RwLock<Vec<BankNotificationSender>>>>,
|
||||
notifcation: BankNotification,
|
||||
) {
|
||||
if let Some(bank_notification_subscribers) = bank_notification_subscribers {
|
||||
for sender in bank_notification_subscribers.read().unwrap().iter() {
|
||||
match sender.send(notifcation.clone()) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
info!(
|
||||
"Failed to send notification {:?}, error: {:?}",
|
||||
notifcation, err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn notify_or_defer(
|
||||
subscriptions: &Arc<RpcSubscriptions>,
|
||||
bank_forks: &Arc<RwLock<BankForks>>,
|
||||
bank: &Arc<Bank>,
|
||||
last_notified_confirmed_slot: &mut Slot,
|
||||
pending_optimistically_confirmed_banks: &mut HashSet<Slot>,
|
||||
confirmed_bank_subscribers: &Option<Arc<RwLock<Vec<Sender<Slot>>>>>,
|
||||
bank_notification_subscribers: &Option<Arc<RwLock<Vec<BankNotificationSender>>>>,
|
||||
) {
|
||||
if bank.is_frozen() {
|
||||
if bank.slot() > *last_notified_confirmed_slot {
|
||||
@ -133,20 +153,10 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
);
|
||||
subscriptions.notify_gossip_subscribers(bank.slot());
|
||||
*last_notified_confirmed_slot = bank.slot();
|
||||
if let Some(confirmed_bank_subscribers) = confirmed_bank_subscribers {
|
||||
for sender in confirmed_bank_subscribers.read().unwrap().iter() {
|
||||
match sender.send(bank.slot()) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
info!(
|
||||
"Failed to send slot {:} update, error: {:?}",
|
||||
bank.slot(),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Self::notify_slot_status(
|
||||
bank_notification_subscribers,
|
||||
BankNotification::OptimisticallyConfirmed(bank.slot()),
|
||||
);
|
||||
}
|
||||
} else if bank.slot() > bank_forks.read().unwrap().root_bank().slot() {
|
||||
pending_optimistically_confirmed_banks.insert(bank.slot());
|
||||
@ -161,7 +171,7 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
slot_threshold: Slot,
|
||||
mut last_notified_confirmed_slot: &mut Slot,
|
||||
mut pending_optimistically_confirmed_banks: &mut HashSet<Slot>,
|
||||
confirmed_bank_subscribers: &Option<Arc<RwLock<Vec<Sender<Slot>>>>>,
|
||||
bank_notification_subscribers: &Option<Arc<RwLock<Vec<BankNotificationSender>>>>,
|
||||
) {
|
||||
for confirmed_bank in bank.clone().parents_inclusive().iter().rev() {
|
||||
if confirmed_bank.slot() > slot_threshold {
|
||||
@ -175,7 +185,7 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
confirmed_bank,
|
||||
&mut last_notified_confirmed_slot,
|
||||
&mut pending_optimistically_confirmed_banks,
|
||||
confirmed_bank_subscribers,
|
||||
bank_notification_subscribers,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -189,7 +199,7 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
mut pending_optimistically_confirmed_banks: &mut HashSet<Slot>,
|
||||
mut last_notified_confirmed_slot: &mut Slot,
|
||||
highest_confirmed_slot: &mut Slot,
|
||||
confirmed_bank_subscribers: &Option<Arc<RwLock<Vec<Sender<Slot>>>>>,
|
||||
bank_notification_subscribers: &Option<Arc<RwLock<Vec<BankNotificationSender>>>>,
|
||||
) {
|
||||
debug!("received bank notification: {:?}", notification);
|
||||
match notification {
|
||||
@ -211,7 +221,7 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
*highest_confirmed_slot,
|
||||
&mut last_notified_confirmed_slot,
|
||||
&mut pending_optimistically_confirmed_banks,
|
||||
confirmed_bank_subscribers,
|
||||
bank_notification_subscribers,
|
||||
);
|
||||
|
||||
*highest_confirmed_slot = slot;
|
||||
@ -245,6 +255,11 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
max_transactions_per_entry: bank.transactions_per_entry_max(),
|
||||
},
|
||||
});
|
||||
|
||||
Self::notify_slot_status(
|
||||
bank_notification_subscribers,
|
||||
BankNotification::Frozen(bank.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
if pending_optimistically_confirmed_banks.remove(&bank.slot()) {
|
||||
@ -260,7 +275,7 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
*last_notified_confirmed_slot,
|
||||
&mut last_notified_confirmed_slot,
|
||||
&mut pending_optimistically_confirmed_banks,
|
||||
confirmed_bank_subscribers,
|
||||
bank_notification_subscribers,
|
||||
);
|
||||
|
||||
let mut w_optimistically_confirmed_bank =
|
||||
@ -272,6 +287,10 @@ impl OptimisticallyConfirmedBankTracker {
|
||||
}
|
||||
}
|
||||
BankNotification::Root(bank) => {
|
||||
Self::notify_slot_status(
|
||||
bank_notification_subscribers,
|
||||
BankNotification::Root(bank.clone()),
|
||||
);
|
||||
let root_slot = bank.slot();
|
||||
let mut w_optimistically_confirmed_bank =
|
||||
optimistically_confirmed_bank.write().unwrap();
|
||||
|
Reference in New Issue
Block a user