Skip to content

Commit

Permalink
Improve active view refresher performance
Browse files Browse the repository at this point in the history
  • Loading branch information
seratch committed Nov 13, 2023
1 parent 2298f2d commit 1647fbc
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 66 deletions.
191 changes: 126 additions & 65 deletions functions/refresh_main_views.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
import { DefineFunction, SlackFunction } from "deno-slack-sdk/mod.ts";
import {
SlackAPIClient,
SlackAPIClient as SlackAPI,
SlackAPIError,
} from "slack-web-api-client/mod.ts";
import { SavedAttributes } from "deno-slack-data-mapper/mod.ts";
import { DataMapper, SavedAttributes } from "deno-slack-data-mapper/mod.ts";

import {
AU,
AUMapper,
AV,
AVMapper,
cleanUpOldActiveViews,
fetchLifelog,
fetchTimeEntry,
L,
LMapper,
OP,
OPMapper,
PH,
PHMapper,
saveLastActiveView,
TE,
TEMapper,
US,
USMapper,
} from "./internals/datastore.ts";
import {
Expand Down Expand Up @@ -45,6 +52,7 @@ export const def = DefineFunction({
});

export default SlackFunction(def, async ({ token, env, client }) => {
const start = new Date();
const isDebugMode: boolean = determineIsDebugMode(env);
const logLevel = determineLogLevel(env);
const slackApi = new SlackAPI(token, { logLevel });
Expand Down Expand Up @@ -75,76 +83,129 @@ export default SlackFunction(def, async ({ token, env, client }) => {
return { error };
}
if (activeViews) {
const now = Math.floor(new Date().getTime() / 1000);
// this view has been kept open for a while
const minutes = 5 * 60;
const foundUsers: string[] = [];
for (const activeView of activeViews) {
try {
if (!foundUsers.includes(activeView.user_id)) {
foundUsers.push(activeView.user_id);
}
const tasks: Promise<void>[] = [];
try {
for (const activeView of activeViews) {
tasks.push(updateActiveView({
isDebugMode,
activeView,
foundUsers,
slackApi,
us,
av,
te,
l,
op,
au,
ph,
}));
}
for (const user_id of foundUsers) {
tasks.push(cleanUpOldActiveViews({ av, user_id }));
}
const all = Promise.all(tasks);
await Promise.race([
all,
new Promise((resolve) => setTimeout(resolve, 14000)),
]);
const end = new Date();
const spentMillis = end.getTime() - start.getTime();
const seconds = Math.floor(spentMillis / 100) / 10;
console.log(`!!! All updates completed within ${seconds} seconds`);
} catch (e) {
console.log(`!!! Failed to complete the tasks: ${e}`);
}
}

return { outputs: {} };
});

if (activeView.last_updated_callback_id === CallbackId.MainView) {
if (activeView.last_updated_at < now - minutes) {
const user = activeView.user_id;
const settings = (await us.findById(user)).item;
const [language, country, offset, isLifelogEnabled] = [
settings.language || LanguageCode.English,
settings.country_id,
settings.offset || 0,
settings.app_mode === AppModeCode.WorkAndLifelogs,
];
const yyyymmdd = todayYYYYMMDD(offset);
try {
const result = await slackApi.views.update({
view_id: activeView.view_id,
view: await toMainView({
view: newView(language),
entry: await fetchTimeEntry({ te, user, offset, yyyymmdd }),
lifelog: isLifelogEnabled
? await fetchLifelog({ l, user, offset, yyyymmdd })
: undefined,
isDebugMode,
isLifelogEnabled,
offset,
language,
country,
manualEntryPermitted: await isManualEntryPermitted({ op }),
canAccessAdminFeature: buildCanAccessAdminFeature(au, user),
holidays: buildHolidays(ph, country, yyyymmdd),
yyyymmdd,
}),
});
await saveLastActiveView({
av,
callback_id: result.view!.callback_id!,
view_id: result.view!.id!,
user_id: user,
});
} catch (e) {
console.log(`Failed to update an active view: ${e}`);
if (e instanceof SlackAPIError) {
const apiError = e as SlackAPIError;
if (apiError.error === "not_found") {
// The modal view seems to be already closed
await av.deleteById(activeView.view_id);
}
}
interface updateActiveViewArgs {
isDebugMode: boolean;
foundUsers: string[];
activeView: SavedAttributes<AV>;
slackApi: SlackAPIClient;
us: DataMapper<US>;
av: DataMapper<AV>;
te: DataMapper<TE>;
l: DataMapper<L>;
op: DataMapper<OP>;
au: DataMapper<AU>;
ph: DataMapper<PH>;
}
async function updateActiveView({
isDebugMode,
foundUsers,
activeView,
slackApi,
us,
av,
te,
l,
op,
au,
ph,
}: updateActiveViewArgs) {
const now = Math.floor(new Date().getTime() / 1000);
// this view has been kept open for a while
const minutes = 5 * 60;
try {
if (!foundUsers.includes(activeView.user_id)) {
foundUsers.push(activeView.user_id);
}
if (activeView.last_updated_callback_id === CallbackId.MainView) {
if (activeView.last_updated_at < now - minutes) {
const user = activeView.user_id;
const settings = (await us.findById(user)).item;
const [language, country, offset, isLifelogEnabled] = [
settings.language || LanguageCode.English,
settings.country_id,
settings.offset || 0,
settings.app_mode === AppModeCode.WorkAndLifelogs,
];
const yyyymmdd = todayYYYYMMDD(offset);
try {
const result = await slackApi.views.update({
view_id: activeView.view_id,
view: await toMainView({
view: newView(language),
entry: await fetchTimeEntry({ te, user, offset, yyyymmdd }),
lifelog: isLifelogEnabled
? await fetchLifelog({ l, user, offset, yyyymmdd })
: undefined,
isDebugMode,
isLifelogEnabled,
offset,
language,
country,
manualEntryPermitted: await isManualEntryPermitted({ op }),
canAccessAdminFeature: buildCanAccessAdminFeature(au, user),
holidays: buildHolidays(ph, country, yyyymmdd),
yyyymmdd,
}),
});
await saveLastActiveView({
av,
callback_id: result.view!.callback_id!,
view_id: result.view!.id!,
user_id: user,
});
} catch (e) {
console.log(`Failed to update an active view: ${e}`);
if (e instanceof SlackAPIError) {
const apiError = e as SlackAPIError;
if (apiError.error === "not_found") {
// The modal view seems to be already closed
await av.deleteById(activeView.view_id);
}
}
}
} catch (e) {
console.log(
`Failed to handle ${JSON.stringify(activeView)} due to ${e}`,
);
}
}
const promises = foundUsers.map((user_id) =>
cleanUpOldActiveViews({ av, user_id })
} catch (e) {
console.log(
`Failed to handle ${JSON.stringify(activeView)} due to ${e}`,
);
await Promise.all(promises);
}

return { outputs: {} };
});
}
2 changes: 1 addition & 1 deletion import_map.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"std/": "https://deno.land/[email protected]/",
"deno-slack-sdk/": "https://deno.land/x/[email protected]/",
"deno-slack-api/": "https://deno.land/x/[email protected]/",
"deno-slack-data-mapper/": "https://deno.land/x/[email protected].0/",
"deno-slack-data-mapper/": "https://deno.land/x/[email protected].1/",
"slack-web-api-client/": "https://deno.land/x/[email protected]/"
}
}

0 comments on commit 1647fbc

Please sign in to comment.