@@ -57,17 +57,30 @@ func (r *Router) Init(ctx context.Context, config *Config, d dns.Client, ohm out
5757 for _ , rule := range config .Rule {
5858 cond , err := rule .BuildCondition ()
5959 if err != nil {
60+ r .closeWebhooks ()
6061 return err
6162 }
6263 rr := & Rule {
6364 Condition : cond ,
6465 Tag : rule .GetTag (),
6566 RuleTag : rule .GetRuleTag (),
6667 }
68+ if wh := rule .GetWebhook (); wh != nil {
69+ notifier , err := NewWebhookNotifier (wh )
70+ if err != nil {
71+ r .closeWebhooks ()
72+ return err
73+ }
74+ rr .Webhook = notifier
75+ }
6776 btag := rule .GetBalancingTag ()
6877 if len (btag ) > 0 {
6978 brule , found := r .balancers [btag ]
7079 if ! found {
80+ if rr .Webhook != nil {
81+ rr .Webhook .Close ()
82+ }
83+ r .closeWebhooks ()
7184 return errors .New ("balancer " , btag , " not found" )
7285 }
7386 rr .Balancer = brule
@@ -80,6 +93,7 @@ func (r *Router) Init(ctx context.Context, config *Config, d dns.Client, ohm out
8093
8194// PickRoute implements routing.Router.
8295func (r * Router ) PickRoute (ctx routing.Context ) (routing.Route , error ) {
96+ originalCtx := ctx
8397 rule , ctx , err := r .pickRouteInternal (ctx )
8498 if err != nil {
8599 return nil , err
@@ -88,6 +102,9 @@ func (r *Router) PickRoute(ctx routing.Context) (routing.Route, error) {
88102 if err != nil {
89103 return nil , err
90104 }
105+ if rule .Webhook != nil {
106+ rule .Webhook .Fire (originalCtx , tag )
107+ }
91108 return & Route {Context : ctx , outboundTag : tag , ruleTag : rule .RuleTag }, nil
92109}
93110
@@ -109,6 +126,11 @@ func (r *Router) ReloadRules(config *Config, shouldAppend bool) error {
109126 defer r .mu .Unlock ()
110127
111128 if ! shouldAppend {
129+ for _ , rule := range r .rules {
130+ if rule .Webhook != nil {
131+ rule .Webhook .Close ()
132+ }
133+ }
112134 r .balancers = make (map [string ]* Balancer , len (config .BalancingRule ))
113135 r .rules = make ([]* Rule , 0 , len (config .Rule ))
114136 }
@@ -125,23 +147,47 @@ func (r *Router) ReloadRules(config *Config, shouldAppend bool) error {
125147 r .balancers [rule .Tag ] = balancer
126148 }
127149
150+ startIdx := len (r .rules )
151+ closeNewWebhooks := func () {
152+ for i := startIdx ; i < len (r .rules ); i ++ {
153+ if r .rules [i ].Webhook != nil {
154+ r .rules [i ].Webhook .Close ()
155+ }
156+ }
157+ r .rules = r .rules [:startIdx ]
158+ }
159+
128160 for _ , rule := range config .Rule {
129161 if r .RuleExists (rule .GetRuleTag ()) {
162+ closeNewWebhooks ()
130163 return errors .New ("duplicate ruleTag " , rule .GetRuleTag ())
131164 }
132165 cond , err := rule .BuildCondition ()
133166 if err != nil {
167+ closeNewWebhooks ()
134168 return err
135169 }
136170 rr := & Rule {
137171 Condition : cond ,
138172 Tag : rule .GetTag (),
139173 RuleTag : rule .GetRuleTag (),
140174 }
175+ if wh := rule .GetWebhook (); wh != nil {
176+ notifier , err := NewWebhookNotifier (wh )
177+ if err != nil {
178+ closeNewWebhooks ()
179+ return err
180+ }
181+ rr .Webhook = notifier
182+ }
141183 btag := rule .GetBalancingTag ()
142184 if len (btag ) > 0 {
143185 brule , found := r .balancers [btag ]
144186 if ! found {
187+ if rr .Webhook != nil {
188+ rr .Webhook .Close ()
189+ }
190+ closeNewWebhooks ()
145191 return errors .New ("balancer " , btag , " not found" )
146192 }
147193 rr .Balancer = brule
@@ -173,6 +219,8 @@ func (r *Router) RemoveRule(tag string) error {
173219 for _ , rule := range r .rules {
174220 if rule .RuleTag != tag {
175221 newRules = append (newRules , rule )
222+ } else if rule .Webhook != nil {
223+ rule .Webhook .Close ()
176224 }
177225 }
178226 r .rules = newRules
@@ -233,8 +281,20 @@ func (r *Router) Start() error {
233281 return nil
234282}
235283
284+ // closeWebhooks closes all webhook notifiers in the current rule set.
285+ func (r * Router ) closeWebhooks () {
286+ for _ , rule := range r .rules {
287+ if rule .Webhook != nil {
288+ rule .Webhook .Close ()
289+ }
290+ }
291+ }
292+
236293// Close implements common.Closable.
237294func (r * Router ) Close () error {
295+ r .mu .Lock ()
296+ defer r .mu .Unlock ()
297+ r .closeWebhooks ()
238298 return nil
239299}
240300
0 commit comments