Skip to content

Commit

Permalink
Fix http trigger could not be schedule by interval (apache#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrproliu authored Aug 8, 2021
1 parent e6651c0 commit 37e1839
Showing 1 changed file with 61 additions and 26 deletions.
87 changes: 61 additions & 26 deletions internal/components/trigger/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package trigger

import (
"context"
"fmt"
"net/http"
"os"
Expand All @@ -28,10 +29,11 @@ import (
)

type httpAction struct {
interval time.Duration
times int
url string
method string
interval time.Duration
times int
url string
method string
executedCount int
}

func NewHTTPAction(intervalStr string, times int, url, method string) Action {
Expand All @@ -50,16 +52,18 @@ func NewHTTPAction(intervalStr string, times int, url, method string) Action {
url = os.ExpandEnv(url)

return &httpAction{
interval: interval,
times: times,
url: url,
method: strings.ToUpper(method),
interval: interval,
times: times,
url: url,
method: strings.ToUpper(method),
executedCount: 0,
}
}

func (h *httpAction) Do() error {
ctx := context.Background()
t := time.NewTicker(h.interval)
c := 1
h.executedCount = 0
client := &http.Client{}
request, err := http.NewRequest(h.method, h.url, nil)
if err != nil {
Expand All @@ -69,29 +73,60 @@ func (h *httpAction) Do() error {

logger.Log.Infof("Trigger will request URL %s %d times, %s seconds apart each time.", h.url, h.times, h.interval)

// execute until success
for range t.C {
logger.Log.Debugf("request URL %s the %d time.", h.url, c)

response, err := client.Do(request)
if err != nil {
logger.Log.Errorf("do request error %v", err)
return err
}
response.Body.Close()

logger.Log.Infof("do request %v response http code %v", h.url, response.StatusCode)
if response.StatusCode == http.StatusOK {
logger.Log.Debugf("do http action %+v success.", *h)
err = h.executeOnce(client, request)
if err == nil {
break
}
if !h.couldContinue() {
logger.Log.Errorf("do request %d times, but still failed", h.times)
return err
}
}

if h.times > 0 {
if h.times <= c {
return fmt.Errorf("do request %d times, but still failed", c)
// background interval trigger
go func() {
for {
select {
case <-t.C:
err = h.executeOnce(client, request)
if !h.couldContinue() {
return
}
case <-ctx.Done():
t.Stop()
return
}
c++
}
}
}()

return nil
}

// execute http request once time
func (h *httpAction) executeOnce(client *http.Client, req *http.Request) error {
logger.Log.Debugf("request URL %s the %d time.", h.url, h.executedCount)
response, err := client.Do(req)
h.executedCount++
if err != nil {
logger.Log.Errorf("do request error %v", err)
return err
}
response.Body.Close()

logger.Log.Infof("do request %v response http code %v", h.url, response.StatusCode)
if response.StatusCode == http.StatusOK {
logger.Log.Debugf("do http action %+v success.", *h)
return nil
}
return fmt.Errorf("do request failed, response status code: %d", response.StatusCode)
}

// verify http action could continue
func (h *httpAction) couldContinue() bool {
if h.times > 0 && h.times <= h.executedCount {
return false
}
return true
}

0 comments on commit 37e1839

Please sign in to comment.