*: abort async fetch on component destroy
* Use AbortController to signal fetch to stop when component is destroyed * Remove polling and just schedule a new fetch at the end of the current one when not aborted.
This commit is contained in:
parent
c6ab1ae54e
commit
32bd112516
|
@ -29,6 +29,8 @@ export default {
|
|||
formatter.use_classes = true;
|
||||
|
||||
return {
|
||||
fetchAbort: null,
|
||||
|
||||
items: [],
|
||||
lastitem: "",
|
||||
lines: [],
|
||||
|
@ -62,75 +64,106 @@ export default {
|
|||
path += "&follow";
|
||||
}
|
||||
|
||||
let res = await fetch(apiurl(path));
|
||||
if (res.status == 200) {
|
||||
const reader = res.body.getReader();
|
||||
try {
|
||||
this.fetching = true;
|
||||
let res = await fetch(apiurl(path), { signal: this.fetchAbort.signal });
|
||||
if (res.status == 200) {
|
||||
const reader = res.body.getReader();
|
||||
|
||||
let lastline = "";
|
||||
let j = 0;
|
||||
for (;;) {
|
||||
let { done, value } = await reader.read();
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
|
||||
let data = new TextDecoder("utf-8").decode(value, { stream: true });
|
||||
|
||||
let part = "";
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
let c = data.charAt(i);
|
||||
if (c == "\r") {
|
||||
// replace lastline from start, simulating line feed (go to start of line)
|
||||
// this isn't perfect since the previous line contents could have
|
||||
// been written using different colors and this will lose them but
|
||||
// in practically all cases this won't happen
|
||||
lastline =
|
||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||
j = 0;
|
||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||
part = "";
|
||||
} else if (c == "\n") {
|
||||
lastline =
|
||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||
j += part.length;
|
||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||
this.items.push(this.lastitem);
|
||||
this.lastitem = "";
|
||||
lastline = "";
|
||||
j = 0;
|
||||
part = "";
|
||||
} else {
|
||||
part += c;
|
||||
let lastline = "";
|
||||
let j = 0;
|
||||
for (;;) {
|
||||
let { done, value } = await reader.read();
|
||||
if (done) {
|
||||
this.fetching = false;
|
||||
return;
|
||||
}
|
||||
|
||||
let data = new TextDecoder("utf-8").decode(value, { stream: true });
|
||||
|
||||
let part = "";
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
let c = data.charAt(i);
|
||||
if (c == "\r") {
|
||||
// replace lastline from start, simulating line feed (go to start of line)
|
||||
// this isn't perfect since the previous line contents could have
|
||||
// been written using different colors and this will lose them but
|
||||
// in practically all cases this won't happen
|
||||
lastline =
|
||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||
j = 0;
|
||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||
part = "";
|
||||
} else if (c == "\n") {
|
||||
lastline =
|
||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||
j += part.length;
|
||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||
this.items.push(this.lastitem);
|
||||
this.lastitem = "";
|
||||
lastline = "";
|
||||
j = 0;
|
||||
part = "";
|
||||
} else {
|
||||
part += c;
|
||||
}
|
||||
}
|
||||
lastline =
|
||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||
j += part.length;
|
||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||
}
|
||||
lastline =
|
||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||
j += part.length;
|
||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO(sgotti) show that log fetching has failed
|
||||
}
|
||||
this.fetching = false;
|
||||
},
|
||||
abortFetch() {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
this.fetchAbort = new AbortController();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show: function(post, pre) {
|
||||
if (pre == false && post == true) {
|
||||
this.abortFetch();
|
||||
this.fetch();
|
||||
}
|
||||
if (pre == true && post == false) {
|
||||
this.abortFetch();
|
||||
}
|
||||
},
|
||||
stepphase: function(post, pre) {
|
||||
if (pre == "notstarted" && post == "running") {
|
||||
stepphase: function(post) {
|
||||
if (!this.show) {
|
||||
return;
|
||||
}
|
||||
if (this.fetching) {
|
||||
return;
|
||||
}
|
||||
if (post == "running") {
|
||||
this.abortFetch();
|
||||
this.getLogs(true);
|
||||
} else {
|
||||
this.abortFetch();
|
||||
this.getLogs(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
if (this.show) {
|
||||
this.fetch();
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
|
||||
if (this.es !== null) {
|
||||
this.es.close();
|
||||
}
|
||||
|
|
|
@ -59,16 +59,21 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
fetchAbort: null,
|
||||
|
||||
fetchProjectGroupsLoading: false,
|
||||
fetchProjectsLoading: false,
|
||||
|
||||
projects: [],
|
||||
projectgroups: [],
|
||||
polling: null
|
||||
projectgroups: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function() {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
this.fetchAbort = new AbortController();
|
||||
this.fetchProjects(this.ownertype, this.ownername);
|
||||
this.fetchProjectGroups(this.ownertype, this.ownername);
|
||||
}
|
||||
|
@ -101,10 +106,14 @@ export default {
|
|||
}
|
||||
|
||||
this.startFetchProjectsLoading();
|
||||
let { data, error } = await fetchProjectGroupProjects(
|
||||
projectgroupref.join("/")
|
||||
let { data, error, aborted } = await fetchProjectGroupProjects(
|
||||
projectgroupref.join("/"),
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
this.stopFetchProjectsLoading();
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
return;
|
||||
|
@ -117,10 +126,14 @@ export default {
|
|||
projectgroupref.push(...this.projectgroupref);
|
||||
}
|
||||
this.startFetchProjectGroupsLoading();
|
||||
let { data, error } = await fetchProjectGroupSubgroups(
|
||||
projectgroupref.join("/")
|
||||
let { data, error, aborted } = await fetchProjectGroupSubgroups(
|
||||
projectgroupref.join("/"),
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
this.stopFetchProjectGroupsLoading();
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
return;
|
||||
|
@ -131,8 +144,14 @@ export default {
|
|||
projectGroupLink: projectGroupLink
|
||||
},
|
||||
created: function() {
|
||||
this.fetchAbort = new AbortController();
|
||||
this.fetchProjects(this.ownertype, this.ownername);
|
||||
this.fetchProjectGroups(this.ownertype, this.ownername);
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -125,13 +125,17 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
now: moment(),
|
||||
|
||||
fetchAbort: null,
|
||||
|
||||
fetchRunsLoading: false,
|
||||
fetchRunsLoadingTimeout: false,
|
||||
fetchRunsError: null,
|
||||
fetchRunsSchedule: null,
|
||||
|
||||
runs: null,
|
||||
wantedRunsNumber: 25,
|
||||
hasMoreRuns: false,
|
||||
polling: null,
|
||||
project: null,
|
||||
user: null
|
||||
};
|
||||
|
@ -163,22 +167,32 @@ export default {
|
|||
return run.tasks_waiting_approval.length > 0;
|
||||
},
|
||||
update() {
|
||||
clearInterval(this.polling);
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
clearTimeout(this.fetchRunsSchedule);
|
||||
if (this.projectref !== undefined) {
|
||||
this.fetchProject();
|
||||
} else {
|
||||
this.fetchUser();
|
||||
}
|
||||
this.pollData();
|
||||
},
|
||||
async fetchProject() {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
let projectref = [
|
||||
this.ownertype,
|
||||
this.ownername,
|
||||
...this.projectref
|
||||
].join("/");
|
||||
|
||||
let { data, error } = await fetchProject(projectref);
|
||||
let { data, error, aborted } = await fetchProject(
|
||||
projectref,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
return;
|
||||
|
@ -188,7 +202,15 @@ export default {
|
|||
this.fetchRuns(true);
|
||||
},
|
||||
async fetchUser() {
|
||||
let { data, error } = await fetchUser(this.ownername);
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
let { data, error, aborted } = await fetchUser(
|
||||
this.ownername,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
return;
|
||||
|
@ -227,10 +249,20 @@ export default {
|
|||
|
||||
if (loading) this.startFetchRunsLoading();
|
||||
while (!stopFetch) {
|
||||
let { data, error } = await fetchRuns(group, startRunID, lastrun);
|
||||
let { data, error, aborted } = await fetchRuns(
|
||||
group,
|
||||
startRunID,
|
||||
lastrun,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.stopFetchRunsLoading();
|
||||
this.fetchRunsError = error;
|
||||
|
||||
this.scheduleFetchRuns();
|
||||
return;
|
||||
}
|
||||
this.fetchRunsError = null;
|
||||
|
@ -247,10 +279,12 @@ export default {
|
|||
this.stopFetchRunsLoading();
|
||||
this.runs = newRuns;
|
||||
this.hasMoreRuns = hasMoreRuns;
|
||||
|
||||
this.scheduleFetchRuns();
|
||||
},
|
||||
pollData() {
|
||||
clearInterval(this.polling);
|
||||
this.polling = setInterval(() => {
|
||||
scheduleFetchRuns() {
|
||||
clearTimeout(this.fetchRunsSchedule);
|
||||
this.fetchRunsSchedule = setTimeout(() => {
|
||||
this.fetchRuns();
|
||||
}, 2000);
|
||||
},
|
||||
|
@ -293,7 +327,10 @@ export default {
|
|||
this.update();
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.polling);
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
clearTimeout(this.fetchRunsSchedule);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -68,9 +68,11 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
fetchAbort: null,
|
||||
|
||||
fetchRunError: null,
|
||||
fetchRunSchedule: null,
|
||||
run: null,
|
||||
polling: null,
|
||||
|
||||
taskWidth: 200,
|
||||
taskHeight: 40,
|
||||
|
@ -81,6 +83,18 @@ export default {
|
|||
tasksDisplay: "graph"
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function() {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
clearTimeout(this.fetchRunSchedule);
|
||||
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
this.fetchRun();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
runTaskLink(task) {
|
||||
if (this.projectref) {
|
||||
|
@ -108,9 +122,17 @@ export default {
|
|||
return "unknown";
|
||||
},
|
||||
async fetchRun() {
|
||||
let { data, error } = await fetchRun(this.runid);
|
||||
let { data, error, aborted } = await fetchRun(
|
||||
this.runid,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.fetchRunError = error;
|
||||
|
||||
this.scheduleFetchRun();
|
||||
return;
|
||||
}
|
||||
this.fetchRunError = null;
|
||||
|
@ -127,19 +149,25 @@ export default {
|
|||
taskID
|
||||
);
|
||||
}
|
||||
|
||||
this.scheduleFetchRun();
|
||||
},
|
||||
pollData() {
|
||||
this.polling = setInterval(() => {
|
||||
scheduleFetchRun() {
|
||||
clearTimeout(this.fetchRunSchedule);
|
||||
this.fetchRunSchedule = setTimeout(() => {
|
||||
this.fetchRun();
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
this.fetchAbort = new AbortController();
|
||||
this.fetchRun();
|
||||
this.pollData();
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.polling);
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
clearTimeout(this.fetchRunSchedule);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<div>Error fetching Run: {{ fetchRunError }}</div>
|
||||
<div>Error fetching Task: {{ fetchTaskError }}</div>
|
||||
</div>
|
||||
<rundetail :run="run" :ownertype="ownertype" :ownername="ownername" :projectref="projectref"/>
|
||||
<rundetail :run="run" :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
||||
<div v-if="task != null">
|
||||
<div class="mt-8 mb-4 flex justify-between items-center">
|
||||
<div class="flex items-center">
|
||||
|
@ -64,13 +64,29 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
fetchAbort: null,
|
||||
|
||||
fetchRunError: null,
|
||||
fetchTaskError: null,
|
||||
|
||||
run: null,
|
||||
task: null,
|
||||
polling: null
|
||||
task: null
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function() {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
clearTimeout(this.fetchRunSchedule);
|
||||
clearTimeout(this.fetchTaskSchedule);
|
||||
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
this.fetchRun();
|
||||
this.fetchTask();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
taskClass(task) {
|
||||
if (task.status == "success") return "is-success";
|
||||
|
@ -81,38 +97,66 @@ export default {
|
|||
return "unknown";
|
||||
},
|
||||
async fetchRun() {
|
||||
let { data, error } = await fetchRun(this.runid);
|
||||
let { data, error, aborted } = await fetchRun(
|
||||
this.runid,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.fetchRunError = error;
|
||||
this.scheduleFetchRun();
|
||||
return;
|
||||
}
|
||||
this.fetchRunError = error;
|
||||
this.run = data;
|
||||
this.scheduleFetchRun();
|
||||
},
|
||||
async fetchTask() {
|
||||
let { data, error } = await fetchTask(this.runid, this.taskid);
|
||||
let { data, error, aborted } = await fetchTask(
|
||||
this.runid,
|
||||
this.taskid,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.fetchTaskError = error;
|
||||
this.scheduleFetchTask();
|
||||
return;
|
||||
}
|
||||
this.fetchTaskError = error;
|
||||
this.task = data;
|
||||
this.scheduleFetchTask();
|
||||
},
|
||||
pollData() {
|
||||
this.polling = setInterval(() => {
|
||||
this.fetchTask();
|
||||
scheduleFetchRun() {
|
||||
clearTimeout(this.fetchRunSchedule);
|
||||
this.fetchRunSchedule = setTimeout(() => {
|
||||
this.fetchRun();
|
||||
}, 2000);
|
||||
},
|
||||
scheduleFetchTask() {
|
||||
clearTimeout(this.fetchTaskSchedule);
|
||||
this.fetchTaskSchedule = setTimeout(() => {
|
||||
this.fetchTask();
|
||||
}, 2000);
|
||||
},
|
||||
approveTask: approveTask
|
||||
},
|
||||
created: function() {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
this.fetchRun();
|
||||
this.fetchTask();
|
||||
this.pollData();
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.polling);
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
clearTimeout(this.fetchRunSchedule);
|
||||
clearTimeout(this.fetchTaskSchedule);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -71,13 +71,16 @@ export async function registerapi(init) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function fetch(url, init) {
|
||||
if (init === undefined) {
|
||||
export async function fetch(url, init, signal) {
|
||||
if (!init) {
|
||||
init = {}
|
||||
}
|
||||
if (init.headers === undefined) {
|
||||
init["headers"] = {}
|
||||
}
|
||||
if (signal) {
|
||||
init["signal"] = signal;
|
||||
}
|
||||
let idToken = getIdToken();
|
||||
if (idToken) {
|
||||
init.headers["Authorization"] = "bearer " + idToken
|
||||
|
|
130
src/util/data.js
130
src/util/data.js
|
@ -1,10 +1,9 @@
|
|||
import { apiurl, loginapi, registerapi } from "@/util/auth";
|
||||
import { fetch as authfetch } from "@/util/auth";
|
||||
import router from "@/router";
|
||||
import { apiurl, fetch as authfetch, loginapi, registerapi } from "@/util/auth";
|
||||
|
||||
export async function fetch(url, init) {
|
||||
export async function fetch(url, init, signal) {
|
||||
try {
|
||||
let res = await authfetch(url, init)
|
||||
let res = await authfetch(url, init, signal)
|
||||
if (!res.ok) {
|
||||
if (res.status === 401) {
|
||||
router.push({ name: "login" })
|
||||
|
@ -31,6 +30,9 @@ export async function fetch(url, init) {
|
|||
return { data: await res.json(), error: null }
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.name == 'AbortError') {
|
||||
return { data: null, error: null, aborted: true, }
|
||||
}
|
||||
return { data: null, error: "api call failed: " + e.message }
|
||||
}
|
||||
}
|
||||
|
@ -82,17 +84,17 @@ export async function register(username, remotesourcename, remoteloginname, remo
|
|||
}
|
||||
}
|
||||
|
||||
export async function fetchCurrentUser() {
|
||||
export async function fetchCurrentUser(signal) {
|
||||
let path = "/user"
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchOrgMembers(orgref) {
|
||||
export async function fetchOrgMembers(orgref, signal) {
|
||||
let path = "/orgs/" + orgref + "/members"
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchRuns(group, startRunID, lastrun) {
|
||||
export async function fetchRuns(group, startRunID, lastrun, signal) {
|
||||
let u = apiurl("/runs");
|
||||
if (group) {
|
||||
u.searchParams.append("group", group)
|
||||
|
@ -104,49 +106,49 @@ export async function fetchRuns(group, startRunID, lastrun) {
|
|||
u.searchParams.append("start", startRunID)
|
||||
}
|
||||
|
||||
return await fetch(u)
|
||||
return await fetch(u, null, signal)
|
||||
}
|
||||
|
||||
export async function fetchRun(runid) {
|
||||
return await fetch(apiurl("/runs/" + runid));
|
||||
export async function fetchRun(runid, signal) {
|
||||
return await fetch(apiurl("/runs/" + runid), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchTask(runid, taskid) {
|
||||
return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid))
|
||||
export async function fetchTask(runid, taskid, signal) {
|
||||
return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid), signal)
|
||||
}
|
||||
|
||||
export async function fetchUser(username) {
|
||||
export async function fetchUser(username, signal) {
|
||||
let path = "/users/" + username
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchProjectGroup(projectgroupref) {
|
||||
export async function fetchProjectGroup(projectgroupref, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchProjectGroupSubgroups(projectgroupref) {
|
||||
export async function fetchProjectGroupSubgroups(projectgroupref, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||
path += "/subgroups";
|
||||
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchProjectGroupProjects(projectgroupref) {
|
||||
export async function fetchProjectGroupProjects(projectgroupref, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||
path += "/projects";
|
||||
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchProject(ref) {
|
||||
export async function fetchProject(ref, signal) {
|
||||
let path = "/projects/" + encodeURIComponent(ref)
|
||||
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchSecrets(ownertype, ref, all) {
|
||||
export async function fetchSecrets(ownertype, ref, all, signal) {
|
||||
let path
|
||||
if (ownertype == "project") {
|
||||
path = "/projects/"
|
||||
|
@ -158,10 +160,10 @@ export async function fetchSecrets(ownertype, ref, all) {
|
|||
if (all) {
|
||||
path += "?tree&removeoverridden";
|
||||
}
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function fetchVariables(ownertype, ref, all) {
|
||||
export async function fetchVariables(ownertype, ref, all, signal) {
|
||||
let path
|
||||
if (ownertype == "project") {
|
||||
path = "/projects/"
|
||||
|
@ -173,10 +175,10 @@ export async function fetchVariables(ownertype, ref, all) {
|
|||
if (all) {
|
||||
path += "?tree&removeoverridden";
|
||||
}
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function createOrganization(orgname, visibility) {
|
||||
export async function createOrganization(orgname, visibility, signal) {
|
||||
let path = "/orgs"
|
||||
let init = {
|
||||
method: "POST",
|
||||
|
@ -185,10 +187,10 @@ export async function createOrganization(orgname, visibility) {
|
|||
visibility: visibility,
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function createUserToken(username, tokenname) {
|
||||
export async function createUserToken(username, tokenname, signal) {
|
||||
let path = "/users/" + username + "/tokens"
|
||||
let init = {
|
||||
method: "POST",
|
||||
|
@ -196,18 +198,18 @@ export async function createUserToken(username, tokenname) {
|
|||
token_name: tokenname,
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function deleteUserToken(username, tokenname) {
|
||||
export async function deleteUserToken(username, tokenname, signal) {
|
||||
let path = "/users/" + username + "/tokens/" + tokenname
|
||||
let init = {
|
||||
method: "DELETE",
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function createUserLinkedAccount(username, remotesourcename, loginname, password) {
|
||||
export async function createUserLinkedAccount(username, remotesourcename, loginname, password, signal) {
|
||||
let path = "/users/" + username + "/linkedaccounts"
|
||||
let init = {
|
||||
method: "POST",
|
||||
|
@ -217,18 +219,18 @@ export async function createUserLinkedAccount(username, remotesourcename, loginn
|
|||
remote_source_login_password: password,
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function deleteLinkedAccount(username, laid) {
|
||||
export async function deleteLinkedAccount(username, laid, signal) {
|
||||
let path = "/users/" + username + "/linkedaccounts/" + laid
|
||||
let init = {
|
||||
method: "DELETE",
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function restartRun(runid, fromStart) {
|
||||
export async function restartRun(runid, fromStart, signal) {
|
||||
let path = "/runs/" + runid + "/actions"
|
||||
let init = {
|
||||
method: "PUT",
|
||||
|
@ -237,10 +239,10 @@ export async function restartRun(runid, fromStart) {
|
|||
from_start: fromStart
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function cancelRun(runid) {
|
||||
export async function cancelRun(runid, signal) {
|
||||
let path = "/runs/" + runid + "/actions"
|
||||
let init = {
|
||||
method: "PUT",
|
||||
|
@ -248,10 +250,10 @@ export async function cancelRun(runid) {
|
|||
action_type: "cancel"
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function stopRun(runid) {
|
||||
export async function stopRun(runid, signal) {
|
||||
let path = "/runs/" + runid + "/actions"
|
||||
let init = {
|
||||
method: "PUT",
|
||||
|
@ -259,10 +261,10 @@ export async function stopRun(runid) {
|
|||
action_type: "stop"
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function approveTask(runid, taskid) {
|
||||
export async function approveTask(runid, taskid, signal) {
|
||||
let path = "/runs/" + runid + "/tasks/" + taskid + "/actions"
|
||||
let init = {
|
||||
method: "PUT",
|
||||
|
@ -270,20 +272,20 @@ export async function approveTask(runid, taskid) {
|
|||
action_type: "approve"
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function fetchRemoteSources() {
|
||||
export async function fetchRemoteSources(signal) {
|
||||
let path = "/remotesources"
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path), null, signal);
|
||||
}
|
||||
|
||||
export async function userRemoteRepos(remotesourceid) {
|
||||
export async function userRemoteRepos(remotesourceid, signal) {
|
||||
let path = "/user/remoterepos/" + remotesourceid
|
||||
return await fetch(apiurl(path));
|
||||
return await fetch(apiurl(path, null, signal));
|
||||
}
|
||||
|
||||
export async function createProjectGroup(parentref, name, visibility) {
|
||||
export async function createProjectGroup(parentref, name, visibility, signal) {
|
||||
let path = "/projectgroups"
|
||||
let init = {
|
||||
method: "POST",
|
||||
|
@ -293,10 +295,10 @@ export async function createProjectGroup(parentref, name, visibility) {
|
|||
visibility: visibility
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function updateProjectGroup(projectgroupref, name, visibility) {
|
||||
export async function updateProjectGroup(projectgroupref, name, visibility, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||
let init = {
|
||||
method: "PUT",
|
||||
|
@ -305,10 +307,10 @@ export async function updateProjectGroup(projectgroupref, name, visibility) {
|
|||
visibility: visibility,
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function createProject(parentref, name, visibility, remotesourcename, remoterepopath) {
|
||||
export async function createProject(parentref, name, visibility, remotesourcename, remoterepopath, signal) {
|
||||
let path = "/projects"
|
||||
let init = {
|
||||
method: "POST",
|
||||
|
@ -320,10 +322,10 @@ export async function createProject(parentref, name, visibility, remotesourcenam
|
|||
repo_path: remoterepopath,
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function updateProject(projectref, name, visibility) {
|
||||
export async function updateProject(projectref, name, visibility, signal) {
|
||||
let path = "/projects/" + encodeURIComponent(projectref)
|
||||
let init = {
|
||||
method: "PUT",
|
||||
|
@ -332,29 +334,29 @@ export async function updateProject(projectref, name, visibility) {
|
|||
visibility: visibility,
|
||||
})
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function deleteProject(projectref) {
|
||||
export async function deleteProject(projectref, signal) {
|
||||
let path = "/projects/" + encodeURIComponent(projectref)
|
||||
let init = {
|
||||
method: "DELETE",
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function projectUpdateRepoLinkedAccount(projectref) {
|
||||
export async function projectUpdateRepoLinkedAccount(projectref, signal) {
|
||||
let path = "/projects/" + encodeURIComponent(projectref) + "/updaterepolinkedaccount"
|
||||
let init = {
|
||||
method: "PUT",
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
||||
|
||||
export async function deleteProjectGroup(projectgroupref) {
|
||||
export async function deleteProjectGroup(projectgroupref, signal) {
|
||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||
let init = {
|
||||
method: "DELETE",
|
||||
}
|
||||
return await fetch(apiurl(path), init)
|
||||
return await fetch(apiurl(path), init, signal)
|
||||
}
|
|
@ -24,7 +24,6 @@ export default {
|
|||
error: null,
|
||||
run: null,
|
||||
code: this.$route.query.code,
|
||||
polling: null,
|
||||
username: null
|
||||
};
|
||||
},
|
||||
|
|
|
@ -168,15 +168,28 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
fetchAbort: null,
|
||||
|
||||
dropdownActive: false,
|
||||
run: null
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function(route) {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
this.run = null;
|
||||
if (route.params.runid) {
|
||||
let { data, error } = await fetchRun(route.params.runid);
|
||||
let { data, error, aborted } = await fetchRun(
|
||||
route.params.runid,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
return;
|
||||
|
@ -199,14 +212,27 @@ export default {
|
|||
}
|
||||
},
|
||||
created: async function() {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
if (this.$route.params.runid) {
|
||||
let { data, error } = await fetchRun(this.$route.params.runid);
|
||||
let { data, error } = await fetchRun(
|
||||
this.$route.params.runid,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
return;
|
||||
}
|
||||
this.run = data;
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -164,15 +164,28 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
fetchAbort: null,
|
||||
|
||||
dropdownActive: false,
|
||||
run: null
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
$route: async function(route) {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
this.fetchAbort = new AbortController();
|
||||
this.run = null;
|
||||
|
||||
if (route.params.runid) {
|
||||
let { data, error } = await fetchRun(route.params.runid);
|
||||
let { data, error, aborted } = await fetchRun(
|
||||
route.params.runid,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
return;
|
||||
|
@ -204,14 +217,27 @@ export default {
|
|||
}
|
||||
},
|
||||
created: async function() {
|
||||
this.fetchAbort = new AbortController();
|
||||
|
||||
if (this.$route.params.runid) {
|
||||
let { data, error } = await fetchRun(this.$route.params.runid);
|
||||
let { data, error, aborted } = await fetchRun(
|
||||
this.$route.params.runid,
|
||||
this.fetchAbort.signal
|
||||
);
|
||||
if (aborted) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
this.$store.dispatch("setError", error);
|
||||
return;
|
||||
}
|
||||
this.run = data;
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.fetchAbort) {
|
||||
this.fetchAbort.abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue