Documentation ¶
Index ¶
- type AsyncSignal
- type BaseSignal
- func (s *BaseSignal[T]) AddListener(listener SignalListener[T], key ...string) int
- func (s *BaseSignal[T]) Emit(ctx context.Context, payload T)
- func (s *BaseSignal[T]) IsEmpty() bool
- func (s *BaseSignal[T]) Len() int
- func (s *BaseSignal[T]) RemoveListener(key string) int
- func (s *BaseSignal[T]) Reset()
- type Signal
- type SignalListener
- type SyncSignal
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AsyncSignal ¶ added in v1.1.0
type AsyncSignal[T any] struct { BaseSignal[T] // contains filtered or unexported fields }
AsyncSignal is a struct that implements the Signal interface. This is the default implementation. It provides the same functionality as the SyncSignal but the listeners are called in a separate goroutine. This means that all listeners are called asynchronously. However, the method waits for all the listeners to finish before returning. If you don't want to wait for the listeners to finish, you can call the Emit method in a separate goroutine.
func (*AsyncSignal[T]) Emit ¶ added in v1.1.0
func (s *AsyncSignal[T]) Emit(ctx context.Context, payload T)
Emit notifies all subscribers of the signal and passes the payload in a asynchronous way.
If the context has a deadline or cancellable property, the listeners must respect it. This means that the listeners should stop processing when the context is cancelled. While emtting it calls the listeners in separate goroutines, so the listeners are called asynchronously. However, it waits for all the listeners to finish before returning. If you don't want to wait for the listeners to finish, you can call the Emit method. Also, you must know that Emit does not guarantee the type safety of the emitted value.
Example:
signal := signals.New[string]() signal.AddListener(func(ctx context.Context, payload string) { // Listener implementation // ... }) signal.Emit(context.Background(), "Hello, world!")
type BaseSignal ¶ added in v1.1.0
type BaseSignal[T any] struct { // contains filtered or unexported fields }
BaseSignal provides the base implementation of the Signal interface. It is intended to be used as an abstract base for underlying signal mechanisms.
Example:
type MyDerivedSignal[T any] struct { BaseSignal[T] // Additional fields or methods specific to MyDerivedSignal } func (s *MyDerivedSignal[T]) Emit(ctx context.Context, payload T) { // Custom implementation for emitting the signal }
func (*BaseSignal[T]) AddListener ¶ added in v1.1.0
func (s *BaseSignal[T]) AddListener(listener SignalListener[T], key ...string) int
AddListener adds a listener to the signal. The listener will be called whenever the signal is emitted. It returns the number of subscribers after the listener was added. It accepts an optional key that can be used to remove the listener later or to check if the listener was already added. It returns -1 if the listener with the same key was already added to the signal.
Example:
signal := signals.New[int]() count := signal.AddListener(func(ctx context.Context, payload int) { // Listener implementation // ... }, "key1") fmt.Println("Number of subscribers after adding listener:", count)
func (*BaseSignal[T]) Emit ¶ added in v1.1.0
func (s *BaseSignal[T]) Emit(ctx context.Context, payload T)
Emit is not implemented in BaseSignal and panics if called. It should be implemented by a derived type.
Example:
type MyDerivedSignal[T any] struct { BaseSignal[T] // Additional fields or methods specific to MyDerivedSignal } func (s *MyDerivedSignal[T]) Emit(ctx context.Context, payload T) { // Custom implementation for emitting the signal }
func (*BaseSignal[T]) IsEmpty ¶ added in v1.1.0
func (s *BaseSignal[T]) IsEmpty() bool
IsEmpty checks if the signal has any subscribers. It returns true if the signal has no subscribers, and false otherwise. This can be used to check if there are any listeners before emitting a signal.
Example:
signal := signals.New[int]() fmt.Println("Is signal empty?", signal.IsEmpty()) // Should print true signal.AddListener(func(ctx context.Context, payload int) { // Listener implementation // ... }) fmt.Println("Is signal empty?", signal.IsEmpty()) // Should print false
func (*BaseSignal[T]) Len ¶ added in v1.1.0
func (s *BaseSignal[T]) Len() int
Len returns the number of listeners subscribed to the signal. This can be used to check how many listeners are currently waiting for a signal. The returned value is of type int.
Example:
signal := signals.New[int]() signal.AddListener(func(ctx context.Context, payload int) { // Listener implementation // ... }) fmt.Println("Number of subscribers:", signal.Len())
func (*BaseSignal[T]) RemoveListener ¶ added in v1.1.0
func (s *BaseSignal[T]) RemoveListener(key string) int
RemoveListener removes a listener from the signal. It returns the number of subscribers after the listener was removed. It returns -1 if the listener was not found.
Example:
signal := signals.New[int]() signal.AddListener(func(ctx context.Context, payload int) { // Listener implementation // ... }, "key1") count := signal.RemoveListener("key1") fmt.Println("Number of subscribers after removing listener:", count)
func (*BaseSignal[T]) Reset ¶ added in v1.1.0
func (s *BaseSignal[T]) Reset()
Reset resets the signal by removing all subscribers from the signal, effectively clearing the list of subscribers. This can be used when you want to stop all listeners from receiving further signals.
Example:
signal := signals.New[int]() signal.AddListener(func(ctx context.Context, payload int) { // Listener implementation // ... }) signal.Reset() // Removes all listeners fmt.Println("Number of subscribers after resetting:", signal.Len())
type Signal ¶
type Signal[T any] interface { // Emit notifies all subscribers of the signal and passes the context and the payload. // // If the context has a deadline or cancellable property, the listeners // must respect it. If the signal is async (default), the listeners are called // in a separate goroutine. // // Example: // signal := signals.New[int]() // signal.AddListener(func(ctx context.Context, payload int) { // // Listener implementation // // ... // }) // signal.Emit(context.Background(), 42) Emit(ctx context.Context, payload T) // AddListener adds a listener to the signal. // // The listener will be called whenever the signal is emitted. It returns the // number of subscribers after the listener was added. It accepts an optional key // that can be used to remove the listener later or to check if the listener // was already added. It returns -1 if the listener with the same key // was already added to the signal. // // Example: // signal := signals.NewSync[int]() // count := signal.AddListener(func(ctx context.Context, payload int) { // // Listener implementation // // ... // }) // fmt.Println("Number of subscribers after adding listener:", count) AddListener(handler SignalListener[T], key ...string) int // RemoveListener removes a listener from the signal. // // It returns the number of subscribers after the listener was removed. // It returns -1 if the listener was not found. // // Example: // signal := signals.NewSync[int]() // signal.AddListener(func(ctx context.Context, payload int) { // // Listener implementation // // ... // }, "key1") // count := signal.RemoveListener("key1") // fmt.Println("Number of subscribers after removing listener:", count) RemoveListener(key string) int // Reset resets the signal by removing all subscribers from the signal, // effectively clearing the list of subscribers. // // This can be used when you want to stop all listeners from receiving // further signals. // // Example: // signal := signals.New[int]() // signal.AddListener(func(ctx context.Context, payload int) { // // Listener implementation // // ... // }) // signal.Reset() // Removes all listeners // fmt.Println("Number of subscribers after resetting:", signal.Len()) Reset() // Len returns the number of listeners subscribed to the signal. // // This can be used to check how many listeners are currently waiting for a signal. // The returned value is of type int. // // Example: // signal := signals.NewSync[int]() // signal.AddListener(func(ctx context.Context, payload int) { // // Listener implementation // // ... // }) // fmt.Println("Number of subscribers:", signal.Len()) Len() int // IsEmpty checks if the signal has any subscribers. // // It returns true if the signal has no subscribers, and false otherwise. // This can be used to check if there are any listeners before emitting a signal. // // Example: // signal := signals.New[int]() // fmt.Println("Is signal empty?", signal.IsEmpty()) // Should print true // signal.AddListener(func(ctx context.Context, payload int) { // // Listener implementation // // ... // }) // fmt.Println("Is signal empty?", signal.IsEmpty()) // Should print false IsEmpty() bool }
Signal is the interface that represents a signal that can be subscribed to emitting a payload of type T.
func New ¶
New creates a new signal that can be used to emit and listen to events asynchronously.
Example:
signal := signals.New[int]() signal.AddListener(func(ctx context.Context, payload int) { // Listener implementation // ... }) signal.Emit(context.Background(), 42)
type SignalListener ¶
SignalListener is a type definition for a function that will act as a listener for signals. This function takes two parameters:
- A context of type `context.Context`. This is typically used for timeout and cancellation signals, and can carry request-scoped values across API boundaries and between processes.
- A payload of generic type `T`. This can be any type, and represents the data or signal that the listener function will process.
The function does not return any value.
type SyncSignal ¶ added in v1.1.0
type SyncSignal[T any] struct { BaseSignal[T] }
SyncSignal is a struct that implements the Signal interface. It provides a synchronous way of notifying all subscribers of a signal. The type parameter `T` is a placeholder for any type.
func (*SyncSignal[T]) Emit ¶ added in v1.1.0
func (s *SyncSignal[T]) Emit(ctx context.Context, payload T)
Emit notifies all subscribers of the signal and passes the payload in a synchronous way.
The payload is of the same type as the SyncSignal's type parameter `T`. The method iterates over the subscribers slice of the SyncSignal, and for each subscriber, it calls the subscriber's listener function, passing the context and the payload. If the context has a deadline or cancellable property, the listeners must respect it. This means that the listeners should stop processing when the context is cancelled. Unlike the AsyncSignal's Emit method, this method does not call the listeners in separate goroutines, so the listeners are called synchronously, one after the other.
Example:
signal := signals.NewSync[string]() signal.AddListener(func(ctx context.Context, payload string) { // Listener implementation // ... }) signal.Emit(context.Background(), "Hello, world!")