package hooks import ( "context" "encoding/json" "errors" "sync" "time" "github.com/sirupsen/logrus" "github.com/wpajqz/go-sdk/export" ) const ( timeout = 5 * time.Second retryInterval = 100 * time.Microsecond ) const ( notifyPath = "/v1/notify" ) var ( defaultClient *Client once = &sync.Once{} ) type Client struct{ tcpClient *export.Client } func (c *Client) Notify(req *NotifyRequest) (*NotifyResponse, error) { if err := req.Check(); err != nil { return nil, err } param, err := json.Marshal(req) if err != nil { return nil, err } var resp NotifyResponse err = c.tcpClient.SyncSend(notifyPath, param, &RequestStatusCallback{ Success: func(header, body []byte) { err = json.Unmarshal(body, &resp) }, Error: func(code int, message string) { err = errors.New(message) }, }) if err != nil { return nil, err } return &resp, err } func NewClient(server string, port int) *Client { once.Do(func() { defaultClient = &Client{tcpClient: export.NewClient(server, port, &ReadyStateCallback{})} ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() for { select { case <-time.After(retryInterval): if defaultClient.tcpClient.GetReadyState() == export.OPEN { return } case <-ctx.Done(): panic("connect link timeout ...") } } }) return defaultClient } func GetClient() *Client { return defaultClient } type ( NotifyRequest struct { Project string `json:"project"` Maintainers []string `json:"maintainers"` Message string `json:"message"` Time string `json:"time"` } NotifyResponse struct { } ) func (ar *NotifyRequest) Check() error { return nil } type ( ReadyStateCallback struct{} RequestStatusCallback struct { Start func() End func() Success func(header, body []byte) Error func(code int, message string) } ) func (readyStateCallback *ReadyStateCallback) OnOpen() { logrus.Info("open link socket connection") } func (readyStateCallback *ReadyStateCallback) OnClose() { logrus.Info("close link socket connection") } func (readyStateCallback *ReadyStateCallback) OnError(err string) { logrus.Infof("error:%s", err) } func (r RequestStatusCallback) OnStart() { if r.Start != nil { r.Start() } } func (r RequestStatusCallback) OnSuccess(header, body []byte) { if r.Success != nil { r.Success(header, body) } } func (r RequestStatusCallback) OnError(code int, message string) { if r.Error != nil { r.Error(code, message) } } func (r RequestStatusCallback) OnEnd() { if r.End != nil { r.End() } }