DoAsync would carry out an asynchronous request
(
method string,
path string,
query url.Values,
body interface{},
header http.Header,
handler plugin.ApiAsyncCallback,
retry int,
)
| 146 | |
| 147 | // DoAsync would carry out an asynchronous request |
| 148 | func (apiClient *ApiAsyncClient) DoAsync( |
| 149 | method string, |
| 150 | path string, |
| 151 | query url.Values, |
| 152 | body interface{}, |
| 153 | header http.Header, |
| 154 | handler plugin.ApiAsyncCallback, |
| 155 | retry int, |
| 156 | ) { |
| 157 | var request func() errors.Error |
| 158 | request = func() errors.Error { |
| 159 | var err error |
| 160 | var res *http.Response |
| 161 | var respBody []byte |
| 162 | |
| 163 | apiClient.logger.Debug("endpoint: %s method: %s header: %s body: %s query: %s", path, method, header, body, query) |
| 164 | res, err = apiClient.Do(method, path, query, body, header) |
| 165 | if err == ErrIgnoreAndContinue { |
| 166 | // make sure defer func got be executed |
| 167 | err = nil //nolint |
| 168 | return nil |
| 169 | } |
| 170 | |
| 171 | // make sure response body is read successfully, or we might have to retry |
| 172 | if err == nil { |
| 173 | // make sure response.Body stream will be closed to avoid running out of file handle |
| 174 | defer func(readCloser io.ReadCloser) { _ = readCloser.Close() }(res.Body) |
| 175 | // replace NetworkStream with MemoryBuffer |
| 176 | respBody, err = io.ReadAll(res.Body) |
| 177 | if err == nil { |
| 178 | res.Body = io.NopCloser(bytes.NewBuffer(respBody)) |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | // check |
| 183 | needRetry := false |
| 184 | errMessage := "unknown" |
| 185 | if err != nil { |
| 186 | needRetry = true |
| 187 | errMessage = err.Error() |
| 188 | } else if res.StatusCode >= HttpMinStatusRetryCode { |
| 189 | needRetry = true |
| 190 | errMessage = fmt.Sprintf("Http DoAsync error calling [method:%s path:%s query:%s]. Response: %s", method, path, query, string(respBody)) |
| 191 | err = errors.HttpStatus(res.StatusCode).New(errMessage) |
| 192 | } |
| 193 | |
| 194 | // if it needs retry, check and retry |
| 195 | if needRetry { |
| 196 | // check whether we still have retry times and not error from handler and canceled error |
| 197 | if retry < apiClient.maxRetry && err != context.Canceled { |
| 198 | apiClient.logger.Warn(err, "retry #%d calling %s", retry, path) |
| 199 | retry++ |
| 200 | apiClient.NextTick(func() errors.Error { |
| 201 | apiClient.SubmitBlocking(request) |
| 202 | return nil |
| 203 | }) |
| 204 | return nil |
| 205 | } |