001/*
002 * Stallion Core: A Modern Web Framework
003 *
004 * Copyright (C) 2015 - 2016 Stallion Software LLC.
005 *
006 * This program is free software: you can redistribute it and/or modify it under the terms of the
007 * GNU General Public License as published by the Free Software Foundation, either version 2 of
008 * the License, or (at your option) any later version. This program is distributed in the hope that
009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
011 * License for more details. You should have received a copy of the GNU General Public License
012 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
013 *
014 *
015 *
016 */
017
018package io.stallion.asyncTasks;
019
020import io.stallion.Context;
021import io.stallion.dataAccess.DataAccessRegistration;
022import io.stallion.dataAccess.StandardModelController;
023import io.stallion.dataAccess.NoStash;
024import io.stallion.dataAccess.db.DB;
025
026import java.util.HashSet;
027import java.util.Set;
028
029import static io.stallion.utils.Literals.*;
030
031
032public class AsyncTaskController extends StandardModelController<AsyncTask> {
033    protected static final String BUCKET_NAME = "async_tasks";
034    protected static final String PATH_NAME = "async-tasks";
035    protected static final String TABLE_NAME = "stallion_async_tasks";
036
037    private static Set<String> _keyFields;
038
039    static {
040        _keyFields = new HashSet<>();
041        _keyFields.add("customKey");
042    }
043
044    public static AsyncTaskController instance() {
045        return (AsyncTaskController) Context.dal().get(BUCKET_NAME);
046    }
047
048    public static void register() {
049        if (DB.available()) {
050            registerDbBased();
051        } else {
052            registerFileBased();
053        }
054    }
055
056
057
058    public static void registerDbBased() {
059        DataAccessRegistration registration = new DataAccessRegistration()
060                .setControllerClass(AsyncTaskController.class)
061                .setModelClass(AsyncTask.class)
062                .setBucket(BUCKET_NAME)
063                .setTableName(TABLE_NAME)
064                .setPersisterClass(AsyncTaskDbPersister.class)
065                .setStashClass(NoStash.class)
066                .setWritable(true);
067        Context.dal().register(registration);
068    }
069
070
071    public static void registerFileBased() {
072        DataAccessRegistration registration = new DataAccessRegistration()
073                .setControllerClass(AsyncTaskController.class)
074                .setModelClass(AsyncTask.class)
075                .setBucket(BUCKET_NAME)
076                .setPath(PATH_NAME)
077                .setPersisterClass(AsyncTaskFilePersister.class)
078                .setWritable(true)
079                .setShouldWatch(true)
080                .setUseDataFolder(true);
081
082        Context.dal().register(registration);
083    }
084
085    /** Registers an ephemeral version of the controller that will not actually store tasks to files.
086     * Used for unittests when we don't want to store the tasks
087     */
088    public static void registerEphemeral() {
089        DataAccessRegistration registration = new DataAccessRegistration()
090                .setControllerClass(AsyncTaskController.class)
091                .setModelClass(AsyncTask.class)
092                .setPath(PATH_NAME)
093                .setBucket(BUCKET_NAME)
094                .setPersisterClass(DummyTaskPersister.class)
095                .setShouldWatch(false)
096                .setUseDataFolder(false)
097                .setWritable(true);
098        Context.dal().register(registration);
099    }
100
101
102
103
104    /**
105     * This gets called when we restart the application and reload all the tasks from the /pending folder
106     * @param task
107     */
108    public void onPostLoadItem(AsyncTask task) {
109        AsyncCoordinator.instance().onLoadTaskOnBoot(task);
110    }
111
112
113
114
115
116
117    public TaskHealthInfo buildHealthInfo() {
118        TaskHealthInfo info = new TaskHealthInfo();
119        info.setPendingTasks(AsyncCoordinator.instance().getPendingTaskCount());
120        //info.setCompletedTasks(seenTaskIds.size());
121        Long thirtyAgo = mils() - 30 * 60 * 1000;
122        info.setStuckTasks(filterChain().filter("originallyScheduledFor", thirtyAgo, "<").filter("completedAt", 0L).count());
123        return info;
124    }
125
126
127
128    @Override
129    public Set<String> getUniqueFields() {
130        return _keyFields;
131    }
132
133    @Override
134    public void reset() {
135        super.reset();
136    }
137
138
139
140}