feature (cancellation): logic to cancel request in client and server

This commit is contained in:
Mickael Kerjean
2022-09-02 17:24:36 +10:00
parent 0bfab6eff2
commit dd6f0ca407
6 changed files with 28 additions and 9 deletions

View File

@ -1,4 +1,4 @@
export function http_get(url, type = "json") { export function http_get(url, type = "json", params) {
return new Promise((done, err) => { return new Promise((done, err) => {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open("GET", url, true); xhr.open("GET", url, true);
@ -30,6 +30,12 @@ export function http_get(url, type = "json") {
xhr.onerror = function() { xhr.onerror = function() {
handle_error_response(xhr, err); handle_error_response(xhr, err);
}; };
if (params && params.abort) {
params.abort.signal.onabort = () => {
xhr.abort();
handle_error_response(xhr, err);
};
}
}); });
} }
@ -152,10 +158,17 @@ function handle_error_response(xhr, err) {
if (navigator.onLine === false) { if (navigator.onLine === false) {
err({ message: "Connection Lost", code: "NO_INTERNET" }); err({ message: "Connection Lost", code: "NO_INTERNET" });
} else if (xhr.status === 0 && xhr.responseText === "") { } else if (xhr.status === 0 && xhr.responseText === "") {
switch(xhr.readyState) {
case XMLHttpRequest.DONE:
case XMLHttpRequest.UNSENT:
err({ message: "aborted", code: "ABORTED" });
break
default:
err({ err({
message: "Service unavailable, if the problem persist, contact your administrator", message: "Service unavailable, if the problem persist, contact your administrator",
code: "INTERNAL_SERVER_ERROR", code: "INTERNAL_SERVER_ERROR",
}); });
}
} else if (xhr.status === 500) { } else if (xhr.status === 500) {
err({ err({
message: message || "Oups something went wrong with our servers", message: message || "Oups something went wrong with our servers",

View File

@ -1,8 +1,13 @@
package common package common
import (
"context"
)
type App struct { type App struct {
Backend IBackend Backend IBackend
Body map[string]interface{} Body map[string]interface{}
Session map[string]string Session map[string]string
Share Share Share Share
Context context.Context
} }

View File

@ -46,7 +46,7 @@ type ISearch interface {
} }
type IAuditPlugin interface { type IAuditPlugin interface {
Query(searchParams map[string]string) (AuditQueryResult, error) Query(ctx *App, searchParams map[string]string) (AuditQueryResult, error)
} }
type AuditQueryResult struct { type AuditQueryResult struct {
Form *Form `json:"form"` Form *Form `json:"form"`

View File

@ -147,7 +147,7 @@ func FetchAuditHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
} }
searchParams[key] = element[0] searchParams[key] = element[0]
} }
result, err := plg.Query(searchParams) result, err := plg.Query(ctx, searchParams)
if err != nil { if err != nil {
SendErrorResult(res, err) SendErrorResult(res, err)
return return

View File

@ -12,13 +12,14 @@ import (
type Middleware func(func(*App, http.ResponseWriter, *http.Request)) func(*App, http.ResponseWriter, *http.Request) type Middleware func(func(*App, http.ResponseWriter, *http.Request)) func(*App, http.ResponseWriter, *http.Request)
func NewMiddlewareChain(fn func(*App, http.ResponseWriter, *http.Request), m []Middleware, app App) http.HandlerFunc { func NewMiddlewareChain(fn func(*App, http.ResponseWriter, *http.Request), m []Middleware, app App) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) { return func(res http.ResponseWriter, req *http.Request) {
var resw ResponseWriter = NewResponseWriter(res) var resw ResponseWriter = NewResponseWriter(res)
var f func(*App, http.ResponseWriter, *http.Request) = fn var f func(*App, http.ResponseWriter, *http.Request) = fn
for i := len(m) - 1; i >= 0; i-- { for i := len(m) - 1; i >= 0; i-- {
f = m[i](f) f = m[i](f)
} }
app.Context = req.Context()
f(&app, &resw, req) f(&app, &resw, req)
if req.Body != nil { if req.Body != nil {
req.Body.Close() req.Body.Close()

View File

@ -57,7 +57,7 @@ var AuditForm Form = Form{
type SimpleAudit struct{} type SimpleAudit struct{}
func (this SimpleAudit) Query(searchParams map[string]string) (AuditQueryResult, error) { func (this SimpleAudit) Query(ctx *App, searchParams map[string]string) (AuditQueryResult, error) {
return AuditQueryResult{ return AuditQueryResult{
Form: &AuditForm, Form: &AuditForm,
RenderHTML: `<style> RenderHTML: `<style>