Skip to content

Commit

Permalink
perf: 定时任务触发/暂停/重启逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
yzqzy committed Feb 1, 2024
1 parent 984eab4 commit 6532846
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 37 deletions.
82 changes: 82 additions & 0 deletions electron/main/cronHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { BrowserWindow, ipcMain } from 'electron'
import ElectronStore from 'electron-store'
import { CronJob } from 'cron'

let win: BrowserWindow | null = null

const SAVED_TASKS_KEY = 'cron_tasks'
const taskMap = new Map()

const createTask = (task: any) => {
const { uid, cron, enabled } = task

console.log(`[corn job]: ${uid} loaded with cron ${cron}, ${enabled}`)

const job = CronJob.from({
cronTime: cron,
onTick: () => {
console.log(`[corn job]: ${uid} triggered`)
win?.webContents.send('main-process-cron-message', task)
},
timeZone: 'Asia/Shanghai'
})

if (enabled) {
job.start()
console.log(`[corn job]: ${uid} starting`)
}

taskMap.set(uid, job)
}

const bindEvents = () => {
ipcMain.on('start-cron-task', (_, task) => {
task = JSON.parse(task)

const { uid } = task
const job = taskMap.get(uid)

if (job) {
job.start()
console.log(`[corn job]: ${uid} restarted`)
return
}

createTask(task)
})
ipcMain.on('stop-cron-task', (_, task) => {
const { uid } = JSON.parse(task)
const job = taskMap.get(uid)

if (!job) return

job.stop()
taskMap.delete(uid)

console.log(`[corn job]: ${uid} stopped`)
})
ipcMain.on('remove-cron-task', (_, task) => {
const { uid } = JSON.parse(task)
const job = taskMap.get(uid)

if (!job) return

job.stop()
taskMap.delete(uid)

console.log(`[corn job]: ${uid} removed`)
})
}

bindEvents()

export function cronHandler(window: BrowserWindow, store: ElectronStore) {
win = window

const tasks = store.get(SAVED_TASKS_KEY, '[]') as string
const savedTasks = JSON.parse(tasks)

if (Array.isArray(savedTasks)) {
savedTasks.forEach(createTask)
}
}
9 changes: 6 additions & 3 deletions electron/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { release } from 'node:os'
import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'

import { injector } from './injectorHandler'
import './storeHandler'
import { injectorHandler } from './injectorHandler'
import { cronHandler } from './cronHandler'
import store from './storeHandler'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
Expand Down Expand Up @@ -92,7 +93,9 @@ async function createWindow() {

app.whenReady().then(() => {
createWindow()
injector()

injectorHandler()
cronHandler(win, store)
})

app.on('window-all-closed', () => {
Expand Down
2 changes: 1 addition & 1 deletion electron/main/injectorHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const okHandler = (event: IpcMainEvent) =>
const errorHandler = (event: IpcMainEvent, message: string) =>
event.sender.send('inject-wxhelper-reply', 'error')

export const injector = () => {
export const injectorHandler = () => {
ipcMain.on('inject-wxhelper', (event, args) => {
const { injectPath, processName, dllPath } = JSON.parse(args)

Expand Down
24 changes: 14 additions & 10 deletions electron/main/storeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ import Store from 'electron-store'

const store = new Store()

ipcMain.handle('get-store-value', (_, key) => {
return store.get(key)
})
ipcMain.handle('set-store-value', (_, key, value) => {
store.set(key, value)
return store.get(key)
})
ipcMain.handle('clear-store', () => {
store.clear()
})
const bindEvents = () => {
ipcMain.handle('get-store-value', (_, key) => {
return store.get(key)
})
ipcMain.handle('set-store-value', (_, key, value) => {
store.set(key, value)
return store.get(key)
})
ipcMain.handle('clear-store', () => {
store.clear()
})
}

bindEvents()

export default store
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
},
"dependencies": {
"axios": "^1.6.5",
"cron": "^3.1.6",
"cronstrue": "^2.47.0",
"electron-store": "^8.1.0",
"element-plus": "^2.5.1",
Expand Down
5 changes: 5 additions & 0 deletions src/demos/ipc.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
window.ipcRenderer.on('main-process-message', (_event, ...args) => {
console.log('[Receive Main-process message]:', ...args)
})

window.ipcRenderer.on('main-process-cron-message', (_event, ...args) => {
console.log('[Receive Main-process corn message]:', ...args)
// TODO: send message
})
2 changes: 1 addition & 1 deletion src/store/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface Task {
name: string
receiver_ids: number[]
cron: string
enable: boolean
enabled: boolean
params: any
}

Expand Down
4 changes: 2 additions & 2 deletions src/views/cron/TaskForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</el-select>
</el-form-item>
<el-form-item label="是否启用">
<el-switch v-model="form.enable"></el-switch>
<el-switch v-model="form.enabled"></el-switch>
</el-form-item>
<el-form-item label="任务参数">
<textarea class="textarea" disabled :value="JSON.stringify(form.params, null, 2)" cols="100" rows="10"></textarea>
Expand Down Expand Up @@ -66,7 +66,7 @@ const form = ref<Task>(props.task || {
mode: TaskMode.CUSTOM,
receiver_ids: [],
cron: '',
enable: false,
enabled: false,
params: {}
});
const cronDesc = computed(() => {
Expand Down
28 changes: 13 additions & 15 deletions src/views/cron/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
<el-table-column label="操作" width="340" align="center">
<template #default="scope">
<el-button type="primary" plain class="btn" @click="handleShowEditTask(scope.$index)">编辑</el-button>
<el-button :type="scope.row.enable ? 'danger' : 'primary'" plain class="btn"
@click="handleEnableTask(scope.$index)">{{ scope.row.enable ? '禁用' :
'启用' }}</el-button>
<el-button type="primary" plain class="btn" @click="handleEnabledTask(scope.$index)">{{ scope.row.enabled ?
'禁用' :
'启用' }}</el-button>
<el-button type="danger" plain class="btn" @click="handleDeleteTask(scope.$index)">删除</el-button>
</template>
</el-table-column>
Expand All @@ -46,16 +46,14 @@ import type { Task } from '../../store/task'
import { useTask } from './useTask'
import { ElMessage, ElMessageBox } from 'element-plus';
const { taskData, addTask, contactData, editTask, removeTask } = useTask()
const { tasks, taskData, contactData, handleAddTask, handleEditTask, handleRemoveTask } = useTask()
const visible = ref(false)
const task = ref<Task>()
const reset = () => {
task.value = undefined
visible.value = false
console.log('reset', task.value)
}
const handleClose = reset
Expand All @@ -64,32 +62,32 @@ const handleShowAddTask = () => {
visible.value = true
}
const handleShowEditTask = (index: number) => {
task.value = _.cloneDeep(taskData.value[index].__origin__)
task.value = _.cloneDeep(tasks.value[index])
visible.value = true
}
const handleConfirm = (data: Task) => {
if (task.value) {
const index = taskData.value.findIndex(item => item.uid === data.uid)
editTask(index, data)
handleEditTask(index, data)
ElMessage.success('编辑成功')
} else {
addTask(data)
handleAddTask(data)
ElMessage.success('新增成功')
}
reset()
}
const handleEnableTask = (index: number) => {
const data = _.cloneDeep(taskData.value[index].__origin__)
const operation = data.enable ? '禁用' : '启用'
const handleEnabledTask = (index: number) => {
const data = _.cloneDeep(tasks.value[index])
const operation = data.enabled ? '禁用' : '启用'
ElMessageBox.confirm(`确定要${operation}该任务吗?`, '提示', {
type: 'warning'
}).then(() => {
editTask(index, {
handleEditTask(index, {
...data,
enable: !data.enable
enabled: !data.enabled
})
ElMessage.success('操作成功')
})
Expand All @@ -99,7 +97,7 @@ const handleDeleteTask = (index: number) => {
ElMessageBox.confirm('确定要删除该任务吗?', '提示', {
type: 'warning'
}).then(() => {
removeTask(index)
handleRemoveTask(index)
ElMessage.success('删除成功')
})
}
Expand Down
41 changes: 36 additions & 5 deletions src/views/cron/useTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,19 @@ import 'cronstrue/locales/zh_CN'
import { Contact, getContactList, messageMapping } from '../../api'

import { storeToRefs } from 'pinia'
import { useTaskStore } from '../../store/task'
import { useTaskStore, Task } from '../../store/task'

const CronTask = {
start: (task: Task) => {
window.ipcRenderer.send('start-cron-task', JSON.stringify(task))
},
stop: (task: Task) => {
window.ipcRenderer.send('stop-cron-task', JSON.stringify(task))
},
remove: (task: Task) => {
window.ipcRenderer.send('remove-cron-task', JSON.stringify(task))
}
}

export const useTask = () => {
const store = useTaskStore()
Expand All @@ -24,7 +36,6 @@ export const useTask = () => {
const taskData = computed(() => {
return tasks.value.map(task => {
return {
__origin__: { ...task },
...task,
type: messageMapping[task.type],
params: JSON.stringify(task.params),
Expand All @@ -46,6 +57,25 @@ export const useTask = () => {
})
}

const handleAddTask = (task: Task) => {
CronTask.start(task)
addTask(task)
}

const handleRemoveTask = (index: number) => {
CronTask.remove(tasks.value[index])
removeTask(index)
}

const handleEditTask = (index: number, task: Task) => {
if (task.enabled) {
CronTask.start(task)
} else {
CronTask.stop(task)
}
editTask(index, task)
}

onMounted(() => {
fetchData()
})
Expand All @@ -54,8 +84,9 @@ export const useTask = () => {
tasks,
taskData,
contactData,
addTask,
removeTask,
editTask

handleAddTask,
handleRemoveTask,
handleEditTask
}
}

0 comments on commit 6532846

Please sign in to comment.