Skip to content

Commit

Permalink
feat: stop experiment on dashboard (#108)
Browse files Browse the repository at this point in the history
* fix #107 

* fix #36
  • Loading branch information
Feudalman authored Dec 30, 2023
1 parent 71630bb commit 300178b
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 6 deletions.
27 changes: 26 additions & 1 deletion swanlab/server/api/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# from ...utils import create_time
from urllib.parse import quote, unquote # 转码路径参数
from typing import List, Dict
from ...utils import get_a_lock
from ...utils import get_a_lock, create_time
from ...log import swanlog as swl

router = APIRouter()
Expand Down Expand Up @@ -329,3 +329,28 @@ async def get_experimet_charts(experiment_id: int):
chart_path: str = os.path.join(swc.root, __find_experiment(experiment_id)["name"], "chart.json")
chart = __get_charts(chart_path)
return SUCCESS_200(chart)


@router.get("/{experiment_id}/stop")
async def get_stop_charts(experiment_id: int):
"""停止实验
Parameters
----------
experiment_id : int
实验唯一ID
"""
config_path: str = os.path.join(swc.root, "project.json")
with open(config_path, mode="r", encoding="utf-8") as f:
config = ujson.load(f)
# 获取需要停止的实验在配置中的索引
index = next((index for index, d in enumerate(config["experiments"]) if d["experiment_id"] == experiment_id), None)
# 修改对应实验的状态
if not config["experiments"][index]["status"] == 0:
# 不在运行中的状态不予修改
return Exception("Experiment status is not running")
config["experiments"][index]["status"] = -1
config["experiments"][index]["update_time"] = create_time()
with get_a_lock(config_path, "w") as f:
ujson.dump(config, f, ensure_ascii=False, indent=4)
return SUCCESS_200({"update_time": create_time()})
2 changes: 1 addition & 1 deletion vue/src/components/SLStatusLabel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const handleClick = () => {

<style lang="scss" scoped>
.sl-status-label {
@apply px-3 py-1 rounded-full text-sm;
@apply px-3 py-1 rounded-full text-sm text-center flex items-center;
}
.stoped {
@apply bg-negative-dimmest text-negative-default;
Expand Down
7 changes: 7 additions & 0 deletions vue/src/i18n/en-US/experiment.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
"cpu": "CPU Count: {value}",
"gpu": "GPU Count: {value}",
"type": "GPU Type: {value}"
},
"stop": {
"button": "Confirm",
"modal": {
"title": "Attention!",
"text": "Should the experiment be stopped as it is irreversible and may result in unpredictable consequences?"
}
}
},
"config": {
Expand Down
7 changes: 6 additions & 1 deletion vue/src/store/modules/experiment.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export const useExperimentStroe = defineStore('charts', () => {
const setStatus = (status) => {
experiment.value.status = status
}
// 修改更新时间
const setUpateTIme = (time) => {
experiment.value.update_time = time
}

return {
// state
Expand All @@ -39,6 +43,7 @@ export const useExperimentStroe = defineStore('charts', () => {
defaultColor,
isRunning,
// action
setStatus
setStatus,
setUpateTIme
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
<div class="flex pb-4">
<div class="min-w-[150px]">{{ $t(`experiment.index.header.experiment_infos.status`) }}</div>
<SLStatusLabel :name="experiment.name" :id="experiment.id" :status="experiment.status" />
<!-- 停止按钮 -->
<StopButton />
</div>
<div v-for="item in experiment_infos" :key="item.title">
<div class="flex pb-4" v-if="item.value">
Expand Down Expand Up @@ -56,6 +58,7 @@ import { formatTime } from '@swanlab-vue/utils/time'
import { t } from '@swanlab-vue/i18n'
import { useExperimentStroe } from '@swanlab-vue/store'
import { ref } from 'vue'
import StopButton from './StopButton.vue'
const experiment = ref(useExperimentStroe().experiment)
Expand All @@ -69,7 +72,7 @@ const experiment_infos = computed(() => {
},
{
title: 'last_time',
value: duration()
value: duration.value
},
{
title: 'version',
Expand Down Expand Up @@ -122,7 +125,7 @@ const experiment_device = computed(() => {
/**
* 计算实验的持续时间
*/
const duration = () => {
const duration = computed(() => {
const time1 = new Date(experiment.value.create_time)
const currentTime = new Date()
const time2 =
Expand Down Expand Up @@ -161,7 +164,7 @@ const duration = () => {
}
return formattedTime.join('')
}
})
</script>
<style lang="scss" scoped>
Expand Down
61 changes: 61 additions & 0 deletions vue/src/views/experiment/pages/index/components/StopButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<button
class="p-2 rounded-full border-2 transition-all duration-200 ml-2"
:class="showColor ? 'border-red-500' : 'cursor-not-allowed'"
@mouseover="() => (hover = true)"
@mouseout="() => (hover = false)"
@click="() => (showWarning = status === 0 && true)"
>
<div class="w-4 h-4 bg-gray-200 transition-all duration-200" :class="showColor ? 'bg-red-500' : ''"></div>
</button>
<SLModal class="px-10 pt-10 pb-5 overflow-hidden" maxW="500" v-model="showWarning">
<div class="w-full">
<h1 class="text-lg font-semibold text-negative-default">{{ $t('experiment.index.header.stop.modal.title') }}</h1>
<p class="py-4">{{ $t('experiment.index.header.stop.modal.text') }}</p>
<div class="flex justify-end">
<button class="px-2 py-1 border transition-all rounded-lg hover:bg-red-500 hover:text-white" @click="confirm">
{{ $t('experiment.index.header.stop.button') }}
</button>
</div>
</div>
</SLModal>
</template>

<script setup>
/**
* @description: 停止实验按钮
* @file: StopButton.vue
* @since: 2023-12-30 20:30:30
**/
import { useExperimentStroe, useProjectStore } from '@swanlab-vue/store'
import { ref } from 'vue'
import { computed } from 'vue'
import SLModal from '@swanlab-vue/components/SLModal.vue'
import http from '@swanlab-vue/api/http'
// ---------------------------------- 弹窗相关 ----------------------------------
const experiment = useExperimentStroe()
const id = experiment.id
const status = experiment.status
const hover = ref(false) // 是否hover
// 展示hover时可点击样式
const showColor = computed(() => {
return status === 0 && hover.value
})
const showWarning = ref(false) // 弹窗状态
// ---------------------------------- 确认删除 ----------------------------------
const confirm = async () => {
const { data } = await http.get(`/experiment/${id}/stop`)
if (!data) return
experiment.setUpateTIme(data.update_time)
useProjectStore().setExperimentStatus(id, -1)
showWarning.value = false
}
</script>

<style lang="scss" scoped></style>

0 comments on commit 300178b

Please sign in to comment.