fix(notify): keep live listen events active when disabled (#2952)

Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
Henry Guo
2026-05-14 01:10:14 +08:00
committed by GitHub
parent d4d07095f8
commit c1bcee327c
5 changed files with 68 additions and 3 deletions
+35
View File
@@ -1150,6 +1150,41 @@ async fn test_listen_notification_emits_after_put_object() -> Result<(), Box<dyn
Ok(())
}
#[tokio::test]
#[serial]
async fn test_listen_notification_emits_on_empty_bucket_when_notify_disabled() -> Result<(), Box<dyn Error + Send + Sync>> {
init_logging();
let mut env = RustFSTestEnvironment::new().await?;
env.start_rustfs_server_with_env(vec![], &[("RUSTFS_NOTIFY_ENABLE", "false")])
.await?;
let bucket = "listen-empty-bucket-e2e";
let key = "seed/object.txt";
let client = env.create_s3_client();
client.create_bucket().bucket(bucket).send().await?;
let listen_url = format!("{}/{bucket}?events={}&ping=1", env.url, urlencoding::encode("s3:ObjectCreated:*"),);
let response = signed_request(http::Method::GET, &listen_url, &env.access_key, &env.secret_key, None, None).await?;
assert_eq!(response.status(), StatusCode::OK);
let read_task = tokio::spawn(read_listen_notification_event(response, key));
client
.put_object()
.bucket(bucket)
.key(key)
.body(ByteStream::from_static(b"empty bucket watch body"))
.send()
.await?;
let payload = timeout(Duration::from_secs(12), read_task).await???;
assert!(!payload.is_empty(), "listen_notification payload should not be empty");
Ok(())
}
#[tokio::test]
#[serial]
async fn test_listen_notification_fans_in_remote_node_events() -> Result<(), Box<dyn Error + Send + Sync>> {
+14
View File
@@ -38,6 +38,20 @@ pub async fn initialize(config: Config) -> Result<(), NotificationError> {
}
}
/// Initialize the global notification system only for live in-process consumers.
///
/// This does not load configured notification targets or bucket rules. It exists so
/// ListenBucketNotification clients can receive live events even when external
/// notification targets are disabled.
pub fn initialize_live_events() -> Result<(), NotificationError> {
let system = NotificationSystem::new(Config::new());
match NOTIFICATION_SYSTEM.set(Arc::new(system)) {
Ok(_) => Ok(()),
Err(_) => Err(NotificationError::Lifecycle(LifecycleError::AlreadyInitialized)),
}
}
/// Returns a handle to the global NotificationSystem instance.
/// Return None if the system has not been initialized.
pub fn notification_system() -> Option<Arc<NotificationSystem>> {
+1 -1
View File
@@ -32,7 +32,7 @@ pub mod stream;
pub use error::{LifecycleError, NotificationError};
pub use event::{Event, EventArgs, EventArgsBuilder};
pub use global::{
initialize, is_notification_system_initialized, notification_metrics_snapshot, notification_system,
initialize, initialize_live_events, is_notification_system_initialized, notification_metrics_snapshot, notification_system,
notification_target_metrics, notifier_global,
};
pub use integration::{NotificationMetricSnapshot, NotificationSystem, NotificationTargetMetricSnapshot};