feat(bus): 进程内事件总线(通配订阅/非阻塞扇出/Close 幂等)
This commit is contained in:
1 parent
c1fb20bd6b
commit
dd16176bb7
4 files changed
+833
No files matched your search
@@ -0,0 +1,63 @@
|
||||
package bus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// match reports whether subject matches pattern using the wildcard rules
|
||||
// described in the package comment: "*" matches exactly one non-empty token,
|
||||
// ">" matches one or more trailing tokens and must be the last token, and any
|
||||
// other token matches an identical subject token. Callers must have validated
|
||||
// both inputs, so an empty token or a misplaced ">" never reaches here.
|
||||
func match(pattern, subject string) bool {
|
||||
p := strings.Split(pattern, ".")
|
||||
s := strings.Split(subject, ".")
|
||||
i, j := 0, 0
|
||||
for i < len(p) {
|
||||
if p[i] == ">" {
|
||||
// ">" is guaranteed to be the last token; it needs at least one
|
||||
// remaining subject token.
|
||||
return j < len(s)
|
||||
}
|
||||
if j >= len(s) {
|
||||
return false
|
||||
}
|
||||
if p[i] != "*" && p[i] != s[j] {
|
||||
return false
|
||||
}
|
||||
i++
|
||||
j++
|
||||
}
|
||||
return j == len(s)
|
||||
}
|
||||
|
||||
// validateSubject rejects an empty subject or one containing an empty token
|
||||
// (leading/trailing/repeated dots).
|
||||
func validateSubject(subject string) error {
|
||||
if subject == "" {
|
||||
return fmt.Errorf("bus: subject must not be empty: %w", ErrInvalidArgument)
|
||||
}
|
||||
if strings.HasPrefix(subject, ".") || strings.HasSuffix(subject, ".") || strings.Contains(subject, "..") {
|
||||
return fmt.Errorf("bus: subject %q contains an empty token: %w", subject, ErrInvalidArgument)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validatePattern rejects an empty pattern, one with an empty token, or one
|
||||
// where the ">" wildcard is not the final token.
|
||||
func validatePattern(pattern string) error {
|
||||
if pattern == "" {
|
||||
return fmt.Errorf("bus: pattern must not be empty: %w", ErrInvalidArgument)
|
||||
}
|
||||
if strings.HasPrefix(pattern, ".") || strings.HasSuffix(pattern, ".") || strings.Contains(pattern, "..") {
|
||||
return fmt.Errorf("bus: pattern %q contains an empty token: %w", pattern, ErrInvalidArgument)
|
||||
}
|
||||
tokens := strings.Split(pattern, ".")
|
||||
for i, tok := range tokens {
|
||||
if tok == ">" && i != len(tokens)-1 {
|
||||
return fmt.Errorf("bus: pattern %q: '>' wildcard must be the last token: %w", pattern, ErrInvalidArgument)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user