Clear task queue logic
This commit is contained in:
parent
57ccf14553
commit
236135f1ca
@ -28,8 +28,8 @@ export class Scheduler {
|
||||
|
||||
private scheduleUniqTask(seconds: number, name: string, args: Args = {}) {
|
||||
const taskScheduler = () => {
|
||||
if (!this.taskQueue.hasNamed(name)) {
|
||||
this.taskQueue.push(name, args, timestamp() + Math.min(seconds, 5 * 60));
|
||||
if (!this.taskQueue.has(t => t.name === name)) {
|
||||
this.scheduleTask(name, args, timestamp() + Math.min(seconds, 5 * 60));
|
||||
}
|
||||
};
|
||||
taskScheduler();
|
||||
@ -48,23 +48,23 @@ export class Scheduler {
|
||||
return this.actionQueue.pop();
|
||||
}
|
||||
|
||||
scheduleTask(name: string, args: Args): void {
|
||||
this.logger.log('PUSH TASK', name, args);
|
||||
scheduleTask(name: string, args: Args, ts?: number | undefined): void {
|
||||
this.logger.log('PUSH TASK', name, args, ts);
|
||||
const villageId = args.villageId;
|
||||
if (isBuildingTask(name)) {
|
||||
this.taskQueue.insertAfterLast(
|
||||
const insertedTs = calculateTimeToPushAfter(
|
||||
this.taskQueue.seeItems(),
|
||||
t => isBuildingTask(t.name) && sameVillage(villageId, t.args),
|
||||
name,
|
||||
args,
|
||||
timestamp()
|
||||
ts
|
||||
);
|
||||
this.taskQueue.push(name, args, insertedTs);
|
||||
} else {
|
||||
this.taskQueue.push(name, args, timestamp());
|
||||
this.taskQueue.push(name, args, ts || timestamp());
|
||||
}
|
||||
}
|
||||
|
||||
completeTask(id: TaskId) {
|
||||
this.taskQueue.complete(id);
|
||||
this.taskQueue.remove(id);
|
||||
this.actionQueue.clear();
|
||||
}
|
||||
|
||||
@ -74,13 +74,16 @@ export class Scheduler {
|
||||
}
|
||||
|
||||
postponeTask(id: TaskId, deltaTs: number) {
|
||||
this.taskQueue.postpone(id, timestamp() + deltaTs);
|
||||
this.taskQueue.modify(
|
||||
t => t.id === id,
|
||||
t => withTime(t, timestamp() + deltaTs)
|
||||
);
|
||||
}
|
||||
|
||||
postponeBuildingsInVillage(villageId: number, seconds: number) {
|
||||
this.taskQueue.modify(
|
||||
t => isBuildingTask(t.name) && sameVillage(villageId, t.args),
|
||||
t => t.withTime(timestamp() + seconds)
|
||||
t => withTime(t, timestamp() + seconds)
|
||||
);
|
||||
}
|
||||
|
||||
@ -100,3 +103,29 @@ function isBuildingTask(taskName: string) {
|
||||
function sameVillage(villageId: number | undefined, args: Args) {
|
||||
return villageId !== undefined && args.villageId === villageId;
|
||||
}
|
||||
|
||||
export function withTime(task: Task, ts: number): Task {
|
||||
return new Task(task.id, ts, task.name, task.args);
|
||||
}
|
||||
|
||||
function calculateTimeToPushAfter(tasks: TaskList, predicate: (t: Task) => boolean, ts: number | undefined): number {
|
||||
const normalizedTs = ts || timestamp();
|
||||
const queuedTaskIndex = findLastIndex(tasks, predicate);
|
||||
if (queuedTaskIndex === undefined) {
|
||||
return normalizedTs;
|
||||
}
|
||||
const queuedTask = tasks[queuedTaskIndex];
|
||||
return Math.max(normalizedTs, queuedTask.ts + 1);
|
||||
}
|
||||
|
||||
function findLastIndex(tasks: TaskList, predicate: (t: Task) => boolean): number | undefined {
|
||||
const count = tasks.length;
|
||||
const indexInReversed = tasks
|
||||
.slice()
|
||||
.reverse()
|
||||
.findIndex(predicate);
|
||||
if (indexInReversed < 0) {
|
||||
return undefined;
|
||||
}
|
||||
return count - 1 - indexInReversed;
|
||||
}
|
||||
|
@ -23,10 +23,6 @@ export class Task {
|
||||
this.name = name;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
withTime(ts: number): Task {
|
||||
return new Task(this.id, ts, this.name, this.args);
|
||||
}
|
||||
}
|
||||
|
||||
export type TaskList = Array<Task>;
|
||||
@ -50,15 +46,6 @@ export class TaskQueue {
|
||||
return task;
|
||||
}
|
||||
|
||||
insertAfterLast(predicate: (t: Task) => boolean, name: string, args: Args, ts: number): Task {
|
||||
const id = uniqTaskId();
|
||||
const task = new Task(id, ts, name, args);
|
||||
this.logger.log('INSERT AFTER TASK', id, ts, name, args);
|
||||
const items = insertTaskAfter(task, this.getItems(), predicate);
|
||||
this.flushItems(items);
|
||||
return task;
|
||||
}
|
||||
|
||||
get(ts: number): Task | undefined {
|
||||
const readyItems = this.getItems().filter(t => t.ts <= ts);
|
||||
if (readyItems.length === 0) {
|
||||
@ -72,30 +59,12 @@ export class TaskQueue {
|
||||
return matched.length > 0;
|
||||
}
|
||||
|
||||
hasNamed(name: string): boolean {
|
||||
return this.has(t => t.name === name);
|
||||
}
|
||||
|
||||
modify(predicate: (t: Task) => boolean, modifier: (t: Task) => Task) {
|
||||
const [matched, other] = this.split(predicate);
|
||||
const modified = matched.map(modifier);
|
||||
this.flushItems(modified.concat(other));
|
||||
}
|
||||
|
||||
complete(id: TaskId) {
|
||||
const [_, items] = this.shiftTask(id);
|
||||
this.flushItems(items);
|
||||
}
|
||||
|
||||
postpone(id: TaskId, newTs: number) {
|
||||
const [task, items] = this.shiftTask(id);
|
||||
if (task) {
|
||||
this.logger.log('POSTPONE', task);
|
||||
items.push(task.withTime(newTs));
|
||||
}
|
||||
this.flushItems(items);
|
||||
}
|
||||
|
||||
remove(id: TaskId) {
|
||||
const [_, items] = this.shiftTask(id);
|
||||
this.flushItems(items);
|
||||
@ -142,27 +111,3 @@ export class TaskQueue {
|
||||
this.storage.set(QUEUE_NAME, normalized);
|
||||
}
|
||||
}
|
||||
|
||||
function insertTaskAfter(task: Task, tasks: TaskList, predicate: (t: Task) => boolean): TaskList {
|
||||
const queuedTaskIndex = findLastIndex(tasks, predicate);
|
||||
if (queuedTaskIndex === undefined) {
|
||||
tasks.push(task);
|
||||
return tasks;
|
||||
}
|
||||
const queuedTask = tasks[queuedTaskIndex];
|
||||
let insertedTask = task.withTime(Math.max(task.ts, queuedTask.ts + 1));
|
||||
tasks.splice(queuedTaskIndex, 0, insertedTask);
|
||||
return tasks;
|
||||
}
|
||||
|
||||
function findLastIndex(tasks: TaskList, predicate: (t: Task) => boolean): number | undefined {
|
||||
const count = tasks.length;
|
||||
const indexInReversed = tasks
|
||||
.slice()
|
||||
.reverse()
|
||||
.findIndex(predicate);
|
||||
if (indexInReversed < 0) {
|
||||
return undefined;
|
||||
}
|
||||
return count - 1 - indexInReversed;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user