How to modify tasks timing in joplin server

I'm trynig to modify timing of tasks in joplin server but without success.
I use a docker compose container on my nas 415+ synology

i have done this

joplin@f2eb21ed640d:~/packages/server$ cd /home/joplin/packages/server/src/utils/
joplin@f2eb21ed640d:~/packages/server/src/utils$ ls
Router.ts cookies.ts joplinUtils.ts requestUtils.ts stripe.ts
TransactionHandler.ts crypto.ts koaIf.ts routeUtils.test.ts testing
array.ts csrf.ts ldapLogin.ts routeUtils.ts time.test.ts
auth.test.ts dbuuid.ts metrics.test.ts setupAppContext.ts time.ts
auth.ts defaultView.ts metrics.ts setupCommands.ts types.ts
base64.ts errors.ts prettycron.testdisabled.ts setupTaskService.ts urlUtils.ts
bytes.test.ts fileUtils.ts prettycron.ts startServices.ts views
bytes.ts htmlUtils.ts renderMarkdown.ts storageConnectionCheck.ts webLogout.ts
cache.ts joplinUtils.test.ts request strings.ts
joplin@f2eb21ed640d:~/packages/server/src/utils$ cat > setupTaskService.ts << 'EOF'

import { Models } from '../models/factory';
import { TaskId } from '../services/database/types';
import TaskService, { Task, taskIdToLabel } from '../services/TaskService';
import { Services } from '../services/types';
import { logHeartbeat as logHeartbeatMessage } from './metrics';
import { Config, Env } from './types';

export default async function(env: Env, models: Models, config: Config, services: Services): Promise {
const taskService = new TaskService(env, models, config, services);

    let tasks: Task[] = [
            // TaskId.DeleteExpiredTokens: Ogni 12 ore (tra 02:00 e 06:00)
            {
                    id: TaskId.DeleteExpiredTokens,
                    description: taskIdToLabel(TaskId.DeleteExpiredTokens),
                    schedule: '0 2,14 * * *',
                    run: (models: Models) => models.token().deleteExpiredTokens(),
            },

            // TaskId.UpdateTotalSizes: 2 volte al giorno (tra 02:00 e 06:00)
            {
                    id: TaskId.UpdateTotalSizes,
                    description: taskIdToLabel(TaskId.UpdateTotalSizes),
                    schedule: '0 2,14 * * *',
                    run: (models: Models) => models.item().updateTotalSizes(),
            },

            // TaskId.CompressOldChanges: Ogni 4 giorni (tra 02:00 e 06:00)
            {
                    id: TaskId.CompressOldChanges,
                    description: taskIdToLabel(TaskId.CompressOldChanges),
                    schedule: '0 2 */4 * *',
                    run: (models: Models) => models.change().compressOldChanges(),
            },

            // TaskId.ProcessUserDeletions: 1 volta al giorno (tra 02:00 e 06:00)
            {
                    id: TaskId.ProcessUserDeletions,
                    description: taskIdToLabel(TaskId.ProcessUserDeletions),
                    schedule: '0 2 * * *',
                    run: (_models: Models, services: Services) => services.userDeletion.runMaintenance(),
            },

            // TaskId.HandleOversizedAccounts: 1 volta al giorno (tra 02:00 e 06:00)
            {
                    id: TaskId.HandleOversizedAccounts,
                    description: taskIdToLabel(TaskId.HandleOversizedAccounts),
                    schedule: '0 2 * * *',
                    run: (models: Models) => models.user().handleOversizedAccounts(),
            },

            // TaskId.DeleteExpiredSessions: 1 volta al giorno (tra 02:00 e 06:00)
            {
                    id: TaskId.DeleteExpiredSessions,
                    description: taskIdToLabel(TaskId.DeleteExpiredSessions),
                    schedule: '0 2 * * *',
                    run: (models: Models) => models.session().deleteExpiredSessions(),
            },

            // TaskId.ProcessOrphanedItems: 1 volta al giorno (tra 02:00 e 06:00)
            {
                    id: TaskId.ProcessOrphanedItems,
                    description: taskIdToLabel(TaskId.ProcessOrphanedItems),
                    schedule: '15 2 * * *',
                    run: (models: Models) => models.item().processOrphanedItems(),
            },

            // TaskId.ProcessShares: Ogni 2 ore (tra 02:00 e 06:00)
            {
                    id: TaskId.ProcessShares,
                    description: taskIdToLabel(TaskId.ProcessShares),
                    schedule: '0 2/2 * * *',
                    run: (models: Models) => models.share().updateSharedItems3(),
            },

            // TaskId.ProcessEmails: Ogni 6 ore (tra 02:00 e 06:00)
            {
                    id: TaskId.ProcessEmails,
                    description: taskIdToLabel(TaskId.ProcessEmails),
                    schedule: '0 2,8 * * *',
                    run: (_models: Models, services: Services) => services.email.runMaintenance(),
            },

            // TaskId.LogHeartbeatMessage: Ogni 3 ore (tra 02:00 e 06:00)
            {
                    id: TaskId.LogHeartbeatMessage,
                    description: taskIdToLabel(TaskId.LogHeartbeatMessage),
                    schedule: '0 2/3 * * *',
                    run: (_models: Models, _services: Services) => logHeartbeatMessage(),
            },
    ];

    if (config.USER_DATA_AUTO_DELETE_ENABLED) {
            tasks.push({
                    // TaskId.AutoAddDisabledAccountsForDeletion: Ogni 3 giorni (tra 02:00 e 06:00)
                    id: TaskId.AutoAddDisabledAccountsForDeletion,
                    description: taskIdToLabel(TaskId.AutoAddDisabledAccountsForDeletion),
                    schedule: '0 2 */3 * *',
                    run: (_models: Models, services: Services) => services.userDeletion.autoAddForDeletion(),
            });
    }

    if (config.isJoplinCloud) {
            tasks = tasks.concat([
                    // TaskId.HandleBetaUserEmails: Ogni 2 giorni (tra 02:00 e 06:00)
                    {
                            id: TaskId.HandleBetaUserEmails,
                            description: taskIdToLabel(TaskId.HandleBetaUserEmails),
                            schedule: '0 2 */2 * *',
                            run: (models: Models) => models.user().handleBetaUserEmails(),
                    },
                    // TaskId.HandleFailedPaymentSubscriptions: Ogni 2 giorni (tra 02:00 e 06:00)
                    {
                            id: TaskId.HandleFailedPaymentSubscriptions,
                            description: taskIdToLabel(TaskId.HandleFailedPaymentSubscriptions),
                            schedule: '0 2 */2 * *',
                            run: (models: Models) => models.user().handleFailedPaymentSubscriptions(),
                    },
            ]);
    }

    await taskService.registerTasks(tasks);

    await taskService.resetInterruptedTasks();

    return taskService;

}
EOF
joplin@f2eb21ed640d:~/packages/server/src/utils$ cat /home/joplin/packages/server/src/utils/setupTaskService.ts

Is there any other file where i can find the timings ?
Thanks
Cesare

Hi Cesare (from a fellow italian user).
I ran into this issue and I worked around it as follows.

First of all, you have to edit the file in dist/utils rather than the one in src/utils. That would be:

/home/joplin/packages/server/dist/utils/setupTaskService.js

(mind the different extension)

I worked around the issue by copying the file on the host, editing it and copying back to a custom image, e.g. with this Dockerfile:

FROM joplin/server:3.3.2-beta
COPY setupTaskService.js /home/joplin/packages/server/dist/utils

Not sure if the Docker host on the Synology will let you do that. Alternatively you may try to edit the file in place; be aware that such modification will persist a container restart but obviously not a rebuild.

Of course it would be best to have a env var to change this schedule (as I see it's been done for config.HEARTBEAT_MESSAGE_SCHEDULE), maybe I'll work on a PR someday.

all the best, -A

Hi Thank you for your answer.
I will try to apply the solution out of curiosity. Not finding how to solve it I continued to look for a system for my notebooks and I came across Trilium nex notes that I am using and that seems to me perhaps even better than Joplin.
I thank you very much for your time and your proposed solution, as soon as I have time I will try it also to try a little Joplin that seems to me an excellent solution anyway!
C.

Hi,
thank you for the hint; Trilium Next is actually an awesome project, even though I think Joplin fits my use case better.

1 Like