github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/tasks.go (about)

     1  /*
     2  *
     3  *	Gosora Task System
     4  *	Copyright Azareal 2017 - 2020
     5  *
     6   */
     7  package common
     8  
     9  import (
    10  	"database/sql"
    11  	"log"
    12  	"time"
    13  
    14  	qgen "github.com/Azareal/Gosora/query_gen"
    15  )
    16  
    17  type TaskStmts struct {
    18  	getExpiredScheduledGroups *sql.Stmt
    19  	getSync                   *sql.Stmt
    20  }
    21  
    22  var Tasks *ScheduledTasks
    23  
    24  type TaskSet interface {
    25  	Add(func() error)
    26  	GetList() []func() error
    27  	Run() error
    28  	Count() int
    29  }
    30  
    31  type DefaultTaskSet struct {
    32  	Tasks []func() error
    33  }
    34  
    35  func (s *DefaultTaskSet) Add(task func() error) {
    36  	s.Tasks = append(s.Tasks, task)
    37  }
    38  
    39  func (s *DefaultTaskSet) GetList() []func() error {
    40  	return s.Tasks
    41  }
    42  
    43  func (s *DefaultTaskSet) Run() error {
    44  	for _, task := range s.Tasks {
    45  		if e := task(); e != nil {
    46  			return e
    47  		}
    48  	}
    49  	return nil
    50  }
    51  
    52  func (s *DefaultTaskSet) Count() int {
    53  	return len(s.Tasks)
    54  }
    55  
    56  type ScheduledTasks struct {
    57  	HalfSec    TaskSet
    58  	Sec        TaskSet
    59  	FifteenMin TaskSet
    60  	Hour       TaskSet
    61  	Day        TaskSet
    62  	Shutdown   TaskSet
    63  }
    64  
    65  func NewScheduledTasks() *ScheduledTasks {
    66  	return &ScheduledTasks{
    67  		HalfSec:    &DefaultTaskSet{},
    68  		Sec:        &DefaultTaskSet{},
    69  		FifteenMin: &DefaultTaskSet{},
    70  		Hour:       &DefaultTaskSet{},
    71  		Day:        &DefaultTaskSet{},
    72  		Shutdown:   &DefaultTaskSet{},
    73  	}
    74  }
    75  
    76  /*var ScheduledHalfSecondTasks []func() error
    77  var ScheduledSecondTasks []func() error
    78  var ScheduledFifteenMinuteTasks []func() error
    79  var ScheduledHourTasks []func() error
    80  var ScheduledDayTasks []func() error
    81  var ShutdownTasks []func() error*/
    82  var taskStmts TaskStmts
    83  var lastSync time.Time
    84  
    85  // TODO: Add a TaskInits.Add
    86  func init() {
    87  	lastSync = time.Now()
    88  	DbInits.Add(func(acc *qgen.Accumulator) error {
    89  		taskStmts = TaskStmts{
    90  			getExpiredScheduledGroups: acc.Select("users_groups_scheduler").Columns("uid").Where("UTC_TIMESTAMP() > revert_at AND temporary = 1").Prepare(),
    91  			getSync:                   acc.Select("sync").Columns("last_update").Prepare(),
    92  		}
    93  		return acc.FirstError()
    94  	})
    95  }
    96  
    97  // AddScheduledHalfSecondTask is not concurrency safe
    98  /*func AddScheduledHalfSecondTask(task func() error) {
    99  	ScheduledHalfSecondTasks = append(ScheduledHalfSecondTasks, task)
   100  }
   101  
   102  // AddScheduledSecondTask is not concurrency safe
   103  func AddScheduledSecondTask(task func() error) {
   104  	ScheduledSecondTasks = append(ScheduledSecondTasks, task)
   105  }
   106  
   107  // AddScheduledFifteenMinuteTask is not concurrency safe
   108  func AddScheduledFifteenMinuteTask(task func() error) {
   109  	ScheduledFifteenMinuteTasks = append(ScheduledFifteenMinuteTasks, task)
   110  }
   111  
   112  // AddScheduledHourTask is not concurrency safe
   113  func AddScheduledHourTask(task func() error) {
   114  	ScheduledHourTasks = append(ScheduledHourTasks, task)
   115  }
   116  
   117  // AddScheduledDayTask is not concurrency safe
   118  func AddScheduledDayTask(task func() error) {
   119  	ScheduledDayTasks = append(ScheduledDayTasks, task)
   120  }
   121  
   122  // AddShutdownTask is not concurrency safe
   123  func AddShutdownTask(task func() error) {
   124  	ShutdownTasks = append(ShutdownTasks, task)
   125  }
   126  
   127  // ScheduledHalfSecondTaskCount is not concurrency safe
   128  func ScheduledHalfSecondTaskCount() int {
   129  	return len(ScheduledHalfSecondTasks)
   130  }
   131  
   132  // ScheduledSecondTaskCount is not concurrency safe
   133  func ScheduledSecondTaskCount() int {
   134  	return len(ScheduledSecondTasks)
   135  }
   136  
   137  // ScheduledFifteenMinuteTaskCount is not concurrency safe
   138  func ScheduledFifteenMinuteTaskCount() int {
   139  	return len(ScheduledFifteenMinuteTasks)
   140  }
   141  
   142  // ScheduledHourTaskCount is not concurrency safe
   143  func ScheduledHourTaskCount() int {
   144  	return len(ScheduledHourTasks)
   145  }
   146  
   147  // ScheduledDayTaskCount is not concurrency safe
   148  func ScheduledDayTaskCount() int {
   149  	return len(ScheduledDayTasks)
   150  }
   151  
   152  // ShutdownTaskCount is not concurrency safe
   153  func ShutdownTaskCount() int {
   154  	return len(ShutdownTasks)
   155  }*/
   156  
   157  // TODO: Use AddScheduledSecondTask
   158  func HandleExpiredScheduledGroups() error {
   159  	rows, e := taskStmts.getExpiredScheduledGroups.Query()
   160  	if e != nil {
   161  		return e
   162  	}
   163  	defer rows.Close()
   164  
   165  	var uid int
   166  	for rows.Next() {
   167  		if e := rows.Scan(&uid); e != nil {
   168  			return e
   169  		}
   170  		// Sneaky way of initialising a *User, please use the methods on the UserStore instead
   171  		user := BlankUser()
   172  		user.ID = uid
   173  		if e = user.RevertGroupUpdate(); e != nil {
   174  			return e
   175  		}
   176  	}
   177  	return rows.Err()
   178  }
   179  
   180  // TODO: Use AddScheduledSecondTask
   181  // TODO: Be a little more granular with the synchronisation
   182  // TODO: Synchronise more things
   183  // TODO: Does this even work?
   184  func HandleServerSync() error {
   185  	// We don't want to run any unnecessary queries when there is nothing to synchronise
   186  	if Config.ServerCount == 1 {
   187  		return nil
   188  	}
   189  
   190  	var lastUpdate time.Time
   191  	e := taskStmts.getSync.QueryRow().Scan(&lastUpdate)
   192  	if e != nil {
   193  		return e
   194  	}
   195  
   196  	if lastUpdate.After(lastSync) {
   197  		if e = Forums.LoadForums(); e != nil {
   198  			log.Print("Unable to reload the forums")
   199  			return e
   200  		}
   201  		// TODO: Resync the groups
   202  		// TODO: Resync the permissions
   203  		if e = LoadSettings(); e != nil {
   204  			log.Print("Unable to reload the settings")
   205  			return e
   206  		}
   207  		if e = WordFilters.ReloadAll(); e != nil {
   208  			log.Print("Unable to reload the word filters")
   209  			return e
   210  		}
   211  	}
   212  	return nil
   213  }