main

mattermost/focalboard

Last updated at: 29/12/2023 09:47

scheduler.go

TLDR

This file defines a package scheduler that contains functions and types related to scheduling tasks. It provides the ability to create both one-time and recurring tasks and cancel them if necessary.

Methods

CreateTask

This method creates a one-time task with the specified name, function, and time to execution.

CreateRecurringTask

This method creates a recurring task with the specified name, function, and interval.

Cancel

This method cancels the scheduled task and waits for its completion. It closes the cancel channel to signal the task to stop.

String

This method returns a formatted string representing the scheduled task's name, interval, and whether it is recurring or not.

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

package scheduler

import (
	"fmt"
	"time"
)

type TaskFunc func()

type ScheduledTask struct {
	Name      string        `json:"name"`
	Interval  time.Duration `json:"interval"`
	Recurring bool          `json:"recurring"`
	function  func()
	cancel    chan struct{}
	cancelled chan struct{}
}

func CreateTask(name string, function TaskFunc, timeToExecution time.Duration) *ScheduledTask {
	return createTask(name, function, timeToExecution, false)
}

func CreateRecurringTask(name string, function TaskFunc, interval time.Duration) *ScheduledTask {
	return createTask(name, function, interval, true)
}

func createTask(name string, function TaskFunc, interval time.Duration, recurring bool) *ScheduledTask {
	task := &ScheduledTask{
		Name:      name,
		Interval:  interval,
		Recurring: recurring,
		function:  function,
		cancel:    make(chan struct{}),
		cancelled: make(chan struct{}),
	}

	go func() {
		defer close(task.cancelled)

		ticker := time.NewTicker(interval)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				function()
			case <-task.cancel:
				return
			}

			if !task.Recurring {
				break
			}
		}
	}()

	return task
}

func (task *ScheduledTask) Cancel() {
	close(task.cancel)
	<-task.cancelled
}

func (task *ScheduledTask) String() string {
	return fmt.Sprintf(
		"%s\nInterval: %s\nRecurring: %t\n",
		task.Name,
		task.Interval.String(),
		task.Recurring,
	)
}