Change task id generation

Id must be generated sequentially
This commit is contained in:
Anton Vakhrushev 2020-04-18 21:47:05 +03:00
parent 3614624aa0
commit a6cc1b5383
8 changed files with 55 additions and 22 deletions

View File

@ -1,7 +1,7 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { BuildingQueueFullError, GrabError } from '../Errors';
import { PostponeAllBuildingsError, GrabError } from '../Errors';
import { grabActiveVillageId, grabBuildingQueueInfo } from '../Page/VillageBlock';
import { BuildingQueueInfo } from '../Game';
@ -10,7 +10,7 @@ export class CheckBuildingRemainingTimeAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
const info = this.grabBuildingQueueInfoOrDefault();
if (info.seconds > 0) {
throw new BuildingQueueFullError(
throw new PostponeAllBuildingsError(
task.id,
grabActiveVillageId(),
info.seconds + 1,

View File

@ -1,17 +1,22 @@
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { GrabError, TryLaterError } from '../Errors';
import { ActionError, GrabError, PostponeAllBuildingsError } from '../Errors';
import { Task } from '../Storage/TaskQueue';
import { clickUpgradeButton } from '../Page/BuildingPage';
@registerAction
export class UpgradeBuildingAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
let villageId = args.villageId;
if (villageId === undefined) {
throw new ActionError(task.id, 'No village id');
}
try {
clickUpgradeButton();
} catch (e) {
if (e instanceof GrabError) {
throw new TryLaterError(task.id, 15 * 60, 'No upgrade button, try later');
throw new PostponeAllBuildingsError(task.id, villageId, 15 * 60, 'No upgrade button, try later');
}
throw e;
}

View File

@ -4,13 +4,13 @@
<div class="container">
<table class="task-table">
<tr v-for="task in shared.taskList" class="task-item" :class="{ 'this-village': isThisVillageTask(task) }">
<td :title="formatDate(task.ts)">{{ formatDate(task.ts) }}</td>
<td :title="task.id">{{ task.id }}</td>
<td>
<td class="time-column" :title="formatDate(task.ts)">{{ formatDate(task.ts) }}</td>
<td class="id-column" :title="task.id">{{ task.id }}</td>
<td class="actions-column">
<a href="#" title="Remove task" class="remove-action" v-on:click.prevent="onRemove(task.id)">&times;</a>
</td>
<td :title="task.name">{{ task.name }}</td>
<td :title="JSON.stringify(task.args)">{{ JSON.stringify(task.args) }}</td>
<td class="name-column" :title="task.name">{{ task.name }}</td>
<td class="args-column" :title="JSON.stringify(task.args)">{{ JSON.stringify(task.args) }}</td>
</tr>
</table>
</div>
@ -66,8 +66,8 @@ export default {
}
.task-item > td {
border-top: 1px solid #ddd;
border-left: 1px solid #ddd;
padding: 2px 4px;
max-width: 25%;
}
.this-village {
color: blue;
@ -76,4 +76,23 @@ export default {
font-weight: bold;
color: red;
}
.time-column,
.actions-column {
max-width: 25%;
}
.id-column {
max-width: 80px;
overflow-x: hidden;
text-overflow: ellipsis;
}
.name-column {
max-width: 80px;
overflow-x: hidden;
text-overflow: ellipsis;
}
.args-column {
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
</style>

View File

@ -51,11 +51,11 @@
<td></td>
</tr>
<tr class="required-line">
<td class="right">Необх:</td>
<td class="right" v-text="village.lumber_need - village.lumber || ''"></td>
<td class="right" v-text="village.clay_need - village.clay || ''"></td>
<td class="right" v-text="village.iron_need - village.iron || ''"></td>
<td class="right" v-text="village.crop_need - village.crop || ''"></td>
<td class="right">Профицит:</td>
<td class="right" v-text="village.lumber - village.lumber_need || ''"></td>
<td class="right" v-text="village.clay - village.clay_need || ''"></td>
<td class="right" v-text="village.iron - village.iron_need || ''"></td>
<td class="right" v-text="village.crop - village.crop_need || ''"></td>
<td></td>
<td></td>
</tr>

View File

@ -37,7 +37,7 @@ export class TryLaterError extends Error {
}
}
export class BuildingQueueFullError extends Error {
export class PostponeAllBuildingsError extends Error {
readonly seconds: number;
readonly villageId: number;
readonly taskId: TaskId;
@ -47,6 +47,6 @@ export class BuildingQueueFullError extends Error {
this.villageId = villageId;
this.taskId = taskId;
this.seconds = seconds;
Object.setPrototypeOf(this, BuildingQueueFullError.prototype);
Object.setPrototypeOf(this, PostponeAllBuildingsError.prototype);
}
}

View File

@ -1,5 +1,5 @@
import { markPage, sleepMicro, timestamp, waitForLoad } from './utils';
import { AbortTaskError, ActionError, BuildingQueueFullError, TryLaterError } from './Errors';
import { AbortTaskError, ActionError, PostponeAllBuildingsError, TryLaterError } from './Errors';
import { Task } from './Storage/TaskQueue';
import { Command } from './Common';
import { TaskQueueRenderer } from './TaskQueueRenderer';
@ -108,7 +108,7 @@ export class Executor {
return;
}
if (err instanceof BuildingQueueFullError) {
if (err instanceof PostponeAllBuildingsError) {
this.logger.warn('BUILDING QUEUE FULL, TRY ALL AFTER', err.seconds);
this.scheduler.postponeBuildingsInVillage(err.villageId, err.seconds);
return;

View File

@ -8,8 +8,17 @@ const QUEUE_NAME = 'queue';
export type TaskId = string;
let idSequence = 1;
let lastTimestamp = null;
function uniqTaskId(): TaskId {
return uniqId();
const ts = Math.floor(Date.now() / 1000);
if (ts === lastTimestamp) {
++idSequence;
} else {
idSequence = 1;
}
return 'tid.' + ts + '.' + String(idSequence).padStart(4, '0') + '.' + uniqId('');
}
export class Task {

View File

@ -44,8 +44,8 @@ function generateId(count: number): string {
return str;
}
export function uniqId(): string {
return 'id' + generateId(6);
export function uniqId(prefix: string = 'id'): string {
return prefix + generateId(6);
}
export function timestamp(): number {