Compare commits

...
This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.

1 Commits

Author SHA1 Message Date
Jarek Radosz
a0899625d5
DEV: Asyncify PreloadStore and its call sites 2022-10-14 13:29:03 +02:00
10 changed files with 123 additions and 138 deletions

View File

@ -5,24 +5,24 @@ import Route from "@ember/routing/route";
export default Route.extend({
// since the logs are pushed via the message bus
// we only want to preload them (hence the beforeModel hook)
beforeModel() {
async beforeModel() {
const logs = this.controllerFor("adminBackupsLogs").get("logs");
// preload the logs if any
PreloadStore.getAndRemove("logs").then(function (preloadedLogs) {
if (preloadedLogs && preloadedLogs.length) {
// we need to filter out message like: "[SUCCESS]"
// and convert POJOs to Ember Objects
const newLogs = preloadedLogs
.filter((log) => {
return log.message.length > 0 && log.message[0] !== "[";
})
.map((log) => EmberObject.create(log));
logs.pushObjects(newLogs);
}
});
const preloadedLogs = await PreloadStore.getAndRemove("logs");
if (preloadedLogs?.length) {
// we need to filter out message like: "[SUCCESS]"
// and convert POJOs to Ember Objects
const newLogs = preloadedLogs
.filter((log) => {
return log.message.length > 0 && log.message[0] !== "[";
})
.map((log) => EmberObject.create(log));
logs.pushObjects(newLogs);
}
},
setupController() {
/* prevent default behavior */
// prevent default behavior
},
});

View File

@ -52,16 +52,16 @@ export default DiscourseRoute.extend({
});
},
model() {
return PreloadStore.getAndRemove("operations_status", () =>
async model() {
const status = await PreloadStore.getAndRemove("operations_status", () =>
ajax("/admin/backups/status.json")
).then((status) =>
BackupStatus.create({
isOperationRunning: status.is_operation_running,
canRollback: status.can_rollback,
allowRestore: status.allow_restore,
})
);
return BackupStatus.create({
isOperationRunning: status.is_operation_running,
canRollback: status.can_rollback,
allowRestore: status.allow_restore,
});
},
deactivate() {

View File

@ -27,17 +27,16 @@ export function finderFor(filter, params) {
}
export default RestAdapter.extend({
find(store, type, findArgs) {
const filter = findArgs.filter;
const params = findArgs.params;
async find(store, type, findArgs) {
const { filter, params } = findArgs;
return PreloadStore.getAndRemove(
const result = await PreloadStore.getAndRemove(
"topic_list",
finderFor(filter, params)
).then(function (result) {
result.filter = filter;
result.params = params;
return result;
});
);
result.filter = filter;
result.params = params;
return result;
},
});

View File

@ -1,6 +1,5 @@
// We can insert data into the PreloadStore when the document is loaded.
// We can insert data into the PreloadStore when the document is loaded.
// The data can be accessed once by a key, after which it is removed
import { Promise } from "rsvp";
export default {
data: new Map(),
@ -15,29 +14,18 @@ export default {
from the store.
So, for example, you can't load a preloaded topic more than once.
**/
getAndRemove(key, finder) {
async getAndRemove(key, finder) {
if (this.data.has(key)) {
let promise = Promise.resolve(this.data.get(key));
const result = this.data.get(key);
this.data.delete(key);
return promise;
return result;
}
if (finder) {
return new Promise(function (resolve, reject) {
let result = finder();
// If the finder returns a promise, we support that too
if (result && result.then) {
result
.then((toResolve) => resolve(toResolve))
.catch((toReject) => reject(toReject));
} else {
resolve(result);
}
});
return await finder();
}
return Promise.resolve(null);
return null;
},
get(key) {

View File

@ -110,17 +110,16 @@ CategoryList.reopenClass({
});
},
list(store) {
const getCategories = () => ajax("/categories.json");
return PreloadStore.getAndRemove("categories_list", getCategories).then(
(result) => {
return CategoryList.create({
categories: this.categoriesFrom(store, result),
can_create_category: result.category_list.can_create_category,
can_create_topic: result.category_list.can_create_topic,
});
}
async list(store) {
const result = await PreloadStore.getAndRemove("categories_list", () =>
ajax("/categories.json")
);
return CategoryList.create({
categories: this.categoriesFrom(store, result),
can_create_category: result.category_list.can_create_category,
can_create_topic: result.category_list.can_create_topic,
});
},
});

View File

@ -665,70 +665,73 @@ const User = RestModel.extend({
return this.stats.rejectBy("isPM");
},
findDetails(options) {
async findDetails(options) {
const user = this;
return PreloadStore.getAndRemove(`user_${user.get("username")}`, () => {
if (options && options.existingRequest) {
// Existing ajax request has been passed, use it
return options.existingRequest;
}
const useCardRoute = options && options.forCard;
if (options) {
delete options.forCard;
}
const path = useCardRoute
? `${user.get("username")}/card.json`
: `${user.get("username")}.json`;
return ajax(userPath(path), { data: options });
}).then((json) => {
if (!isEmpty(json.user.stats)) {
json.user.stats = User.groupStats(
json.user.stats.map((s) => {
if (s.count) {
s.count = parseInt(s.count, 10);
}
return UserActionStat.create(s);
})
);
}
if (!isEmpty(json.user.groups) && !isEmpty(json.user.group_users)) {
const groups = [];
for (let i = 0; i < json.user.groups.length; i++) {
const group = Group.create(json.user.groups[i]);
group.group_user = json.user.group_users[i];
groups.push(group);
const json = await PreloadStore.getAndRemove(
`user_${user.get("username")}`,
() => {
if (options?.existingRequest) {
// Existing ajax request has been passed, use it
return options.existingRequest;
}
json.user.groups = groups;
const useCardRoute = options?.forCard;
if (options) {
delete options.forCard;
}
const path = useCardRoute
? `${user.get("username")}/card.json`
: `${user.get("username")}.json`;
return ajax(userPath(path), { data: options });
}
);
if (!isEmpty(json.user.stats)) {
json.user.stats = User.groupStats(
json.user.stats.map((s) => {
if (s.count) {
s.count = parseInt(s.count, 10);
}
return UserActionStat.create(s);
})
);
}
if (!isEmpty(json.user.groups) && !isEmpty(json.user.group_users)) {
const groups = [];
for (let i = 0; i < json.user.groups.length; i++) {
const group = Group.create(json.user.groups[i]);
group.group_user = json.user.group_users[i];
groups.push(group);
}
if (json.user.invited_by) {
json.user.invited_by = User.create(json.user.invited_by);
}
json.user.groups = groups;
}
if (!isEmpty(json.user.featured_user_badge_ids)) {
const userBadgesMap = {};
UserBadge.createFromJson(json).forEach((userBadge) => {
userBadgesMap[userBadge.get("id")] = userBadge;
});
json.user.featured_user_badges = json.user.featured_user_badge_ids.map(
(id) => userBadgesMap[id]
);
}
if (json.user.invited_by) {
json.user.invited_by = User.create(json.user.invited_by);
}
if (json.user.card_badge) {
json.user.card_badge = Badge.create(json.user.card_badge);
}
if (!isEmpty(json.user.featured_user_badge_ids)) {
const userBadgesMap = {};
UserBadge.createFromJson(json).forEach((userBadge) => {
userBadgesMap[userBadge.get("id")] = userBadge;
});
json.user.featured_user_badges = json.user.featured_user_badge_ids.map(
(id) => userBadgesMap[id]
);
}
user.setProperties(json.user);
return user;
});
if (json.user.card_badge) {
json.user.card_badge = Badge.create(json.user.card_badge);
}
user.setProperties(json.user);
return user;
},
findStaffInfo() {

View File

@ -6,13 +6,12 @@ import { scrollTop } from "discourse/mixins/scroll-top";
import { action } from "@ember/object";
export default DiscourseRoute.extend({
model() {
async model() {
if (PreloadStore.get("badges")) {
return PreloadStore.getAndRemove("badges").then((json) =>
Badge.createFromJson(json)
);
const json = await PreloadStore.getAndRemove("badges");
return Badge.createFromJson(json);
} else {
return Badge.findAll({ onlyListable: true });
return await Badge.findAll({ onlyListable: true });
}
},

View File

@ -29,7 +29,7 @@ export default DiscourseRoute.extend({
});
},
model(params) {
async model(params) {
const cached = getTransient("lastSearch");
let args = { q: params.q };
if (params.context_id && !args.skip_context) {
@ -47,22 +47,21 @@ export default DiscourseRoute.extend({
return cached.data.model;
}
return PreloadStore.getAndRemove("search", () => {
const results = await PreloadStore.getAndRemove("search", () => {
if (isValidSearchTerm(params.q, this.siteSettings)) {
return ajax("/search", { data: args });
} else {
return null;
}
}).then(async (results) => {
const grouped_search_result = results
? results.grouped_search_result
: {};
const model = (results && (await translateResults(results))) || {
grouped_search_result,
};
setTransient("lastSearch", { searchKey, model }, 5);
return model;
});
const grouped_search_result = results ? results.grouped_search_result : {};
let model = results && (await translateResults(results));
model ||= { grouped_search_result };
setTransient("lastSearch", { searchKey, model }, 5);
return model;
},
@action

View File

@ -8,11 +8,10 @@ export default DiscourseRoute.extend({
return I18n.t("invites.accept_title");
},
model(params) {
async model(params) {
if (PreloadStore.get("invite_info")) {
return PreloadStore.getAndRemove("invite_info").then((json) =>
deepMerge(params, json)
);
const json = await PreloadStore.getAndRemove("invite_info");
return deepMerge(params, json);
} else {
return {};
}

View File

@ -10,11 +10,10 @@ export default DiscourseRoute.extend({
return I18n.t("login.reset_password");
},
model(params) {
async model(params) {
if (PreloadStore.get("password_reset")) {
return PreloadStore.getAndRemove("password_reset").then((json) =>
deepMerge(params, json)
);
const json = await PreloadStore.getAndRemove("password_reset");
return deepMerge(params, json);
}
},