Files
golib/notify/example_test.go
2026-01-24 20:35:40 +11:00

251 lines
4.9 KiB
Go

package notify_test
import (
"fmt"
"time"
"git.haelnorr.com/h/golib/notify"
)
// Example demonstrates basic usage of the notify package.
func Example() {
// Create a notifier with 50-notification buffer per subscriber
n := notify.NewNotifier(50)
defer n.Close()
// Subscribe to receive notifications
sub, err := n.Subscribe()
if err != nil {
panic(err)
}
defer sub.Unsubscribe()
// Listen for notifications in a goroutine
done := make(chan bool)
go func() {
for notification := range sub.Listen() {
fmt.Printf("%s: %s\n", notification.Level, notification.Message)
}
done <- true
}()
// Send a notification
n.Notify(notify.Notification{
Target: sub.ID,
Level: notify.LevelSuccess,
Message: "Welcome!",
})
// Give time for processing
time.Sleep(10 * time.Millisecond)
// Cleanup
sub.Unsubscribe()
<-done
// Output:
// success: Welcome!
}
// ExampleNotifier_Subscribe demonstrates subscribing to notifications.
func ExampleNotifier_Subscribe() {
n := notify.NewNotifier(50)
defer n.Close()
// Subscribe
sub, err := n.Subscribe()
if err != nil {
panic(err)
}
fmt.Printf("Subscribed with ID: %s\n", sub.ID[:8]+"...")
sub.Unsubscribe()
// Output will vary due to random ID
}
// ExampleNotifier_Notify demonstrates sending a targeted notification.
func ExampleNotifier_Notify() {
n := notify.NewNotifier(50)
defer n.Close()
sub, _ := n.Subscribe()
defer sub.Unsubscribe()
// Listen in background
done := make(chan bool)
go func() {
notif := <-sub.Listen()
fmt.Printf("Level: %s, Message: %s\n", notif.Level, notif.Message)
done <- true
}()
// Send targeted notification
n.Notify(notify.Notification{
Target: sub.ID,
Level: notify.LevelInfo,
Message: "Hello subscriber",
})
<-done
// Output:
// Level: info, Message: Hello subscriber
}
// ExampleNotifier_NotifyAll demonstrates broadcasting to all subscribers.
func ExampleNotifier_NotifyAll() {
n := notify.NewNotifier(50)
defer n.Close()
// Create multiple subscribers
sub1, _ := n.Subscribe()
sub2, _ := n.Subscribe()
defer sub1.Unsubscribe()
defer sub2.Unsubscribe()
// Listen on both
done := make(chan bool, 2)
listen := func(sub *notify.Subscriber, id int) {
notif := <-sub.Listen()
fmt.Printf("Sub %d received: %s\n", id, notif.Message)
done <- true
}
go listen(sub1, 1)
go listen(sub2, 2)
// Broadcast to all
n.NotifyAll(notify.Notification{
Level: notify.LevelSuccess,
Message: "Broadcast message",
})
// Wait for both
<-done
<-done
// Output will vary in order, but both will print:
// Sub 1 received: Broadcast message
// Sub 2 received: Broadcast message
}
// ExampleNotifier_Close demonstrates graceful shutdown.
func ExampleNotifier_Close() {
n := notify.NewNotifier(50)
sub, _ := n.Subscribe()
// Listen for closure
done := make(chan bool)
go func() {
for range sub.Listen() {
// Process notifications
}
fmt.Println("Listener exited - channel closed")
done <- true
}()
// Close notifier
n.Close()
// Wait for listener to detect closure
<-done
// Try to subscribe after close
_, err := n.Subscribe()
if err != nil {
fmt.Println("Subscribe failed:", err)
}
// Output:
// Listener exited - channel closed
// Subscribe failed: notifier is closed
}
// ExampleSubscriber_Unsubscribe demonstrates unsubscribing.
func ExampleSubscriber_Unsubscribe() {
n := notify.NewNotifier(50)
defer n.Close()
sub, _ := n.Subscribe()
// Listen for closure
done := make(chan bool)
go func() {
for range sub.Listen() {
// Process
}
fmt.Println("Unsubscribed")
done <- true
}()
// Unsubscribe
sub.Unsubscribe()
<-done
// Safe to call again
sub.Unsubscribe()
fmt.Println("Second unsubscribe is safe")
// Output:
// Unsubscribed
// Second unsubscribe is safe
}
// ExampleNotification demonstrates creating notifications with different levels.
func ExampleNotification() {
levels := []notify.Level{
notify.LevelSuccess,
notify.LevelInfo,
notify.LevelWarn,
notify.LevelError,
}
for _, level := range levels {
notif := notify.Notification{
Level: level,
Title: "Example",
Message: fmt.Sprintf("This is a %s message", level),
}
fmt.Printf("%s: %s\n", notif.Level, notif.Message)
}
// Output:
// success: This is a success message
// info: This is a info message
// warn: This is a warn message
// error: This is a error message
}
// ExampleNotification_withAction demonstrates using the Action field.
func ExampleNotification_withAction() {
type CustomAction struct {
URL string
}
n := notify.NewNotifier(50)
defer n.Close()
sub, _ := n.Subscribe()
defer sub.Unsubscribe()
done := make(chan bool)
go func() {
notif := <-sub.Listen()
if action, ok := notif.Action.(CustomAction); ok {
fmt.Printf("Action URL: %s\n", action.URL)
}
done <- true
}()
n.Notify(notify.Notification{
Target: sub.ID,
Level: notify.LevelInfo,
Action: CustomAction{URL: "/dashboard"},
})
<-done
// Output:
// Action URL: /dashboard
}