Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加定时任务命令显示和定时规则显示 #145

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
33 changes: 23 additions & 10 deletions bin/csctl/cmd/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,39 +71,52 @@ var (
valBuf = make([]byte, 1024)
)

func fixRead(r io.Reader, p []byte) (int, error) {
valLen, readLen := len(p), 0
for readLen != valLen {
n, err := r.Read(p[readLen:])
readLen += n
if err != nil {
return readLen, err
}
}
return readLen, nil
}


func restoreKvs(r io.Reader, keyPrefix string, storeChan chan *kv, wg *sync.WaitGroup) error {
for {
// read length of key
n, err := r.Read(keyLenBuf)
n, err := fixRead(r, keyLenBuf)
if err == io.EOF && n != 0 {
return fmt.Errorf("unexcepted data, the file may broken")
} else if err == io.EOF && n == 0 {
break
} else if err != nil {
return err
}
keylen := binary.LittleEndian.Uint16(keyLenBuf)
keyLen := binary.LittleEndian.Uint16(keyLenBuf)

// read key
if n, err = r.Read(keyBuf[:keylen]); err != nil {
if n, err = fixRead(r, keyBuf[:keyLen]); err != nil {
return err
}
key := keyBuf[:keylen]
key := keyBuf[:keyLen]

// read length of value
if n, err = r.Read(valLenBuf); err != nil {
if n, err = fixRead(r, valLenBuf); err != nil {
return err
}
vallen := binary.LittleEndian.Uint32(valLenBuf)
valLen := binary.LittleEndian.Uint32(valLenBuf)

// read value
if len(valBuf) < int(vallen) {
valBuf = make([]byte, vallen*2)
if len(valBuf) < int(valLen) {
valBuf = make([]byte, valLen*2)
}
if n, err = r.Read(valBuf[:vallen]); err != nil && err != io.EOF {
if n, err = fixRead(r, valBuf[:valLen]); err != nil && err != io.EOF {
return err
}
value := valBuf[:vallen]
value := valBuf[:valLen]

wg.Add(1)
storeChan <- &kv{
Expand Down
2 changes: 1 addition & 1 deletion web/ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default {

created: function() {
this.locale = window.$.cookie('locale');
this.$store.commit('setShowWithHostname', window.$.cookie('hostshows') === 'hostname');
this.$store.commit('setShowWithHostname', !(window.$.cookie('hostshows') === 'ip'));
},

computed: {
Expand Down
81 changes: 47 additions & 34 deletions web/ui/src/components/Job.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<style scope>
.clearfix:after {content:""; clear:both; display:table;}
.ui.fitted.checkbox {min-height: 15px;}
.table tbody .cmd-box td {padding: 0.2em 0 0.2em 1em !important ;background:black;color:#06f902;}
.table tbody .cmd-box{padding: 0.2em 0 0.2em 1em !important ;background:black;color:#06f902;}
</style>
<template>
<div>
Expand Down Expand Up @@ -43,39 +45,42 @@
</tr>
</thead>
<tbody>
<tr v-for="(job, index) in jobs">
<td class="center aligned">
<div class="ui icon dropdown" v-show="!batched">
<i class="content icon"></i>
<div class="menu">
<div class="item" v-on:click="editJob(job.group, job.id)">{{$L('edit')}}</div>
<div class="item" v-if="job.pause" v-on:click="changeStatus(job.group, job.id, index, !job.pause)">{{$L('open')}}</div>
<div class="item" v-if="!job.pause" v-on:click="changeStatus(job.group, job.id, index, !job.pause)">{{$L('pause')}}</div>
<div class="divider"></div>
<div class="item" style="color:red;" v-on:click="removeJob(job.group, job.id, index)">{{$L('delete')}}</div>
<template v-for="(job, index) in jobs">
<tr>
<td class="center aligned">
<div class="ui icon dropdown" v-show="!batched">
<i class="content icon"></i>
<div class="menu">
<div class="item" v-on:click="editJob(job.group, job.id)">{{$L('edit')}}</div>
<div class="item" v-if="job.pause" v-on:click="changeStatus(job.group, job.id, index, !job.pause)">{{$L('open')}}</div>
<div class="item" v-if="!job.pause" v-on:click="changeStatus(job.group, job.id, index, !job.pause)">{{$L('pause')}}</div>
<div class="divider"></div>
<div class="item" style="color:red;" v-on:click="removeJob(job.group, job.id, index)">{{$L('delete')}}</div>
</div>
</div>
</div>
<div class="ui fitted checkbox" v-show="batched">
<input type="checkbox" :value="job.group+'/'+job.id" v-model="batchIds"><label></label>
</div>
</td>
<td class="center aligned"><i class="icon" v-bind:class="{pause: job.pause, play: !job.pause, green: !job.pause}"></i></td>
<td>{{job.group}}</td>
<td>{{job.user && job.user.length > 0 ? job.user : '-'}}</td>
<td><router-link :to="buildEditJobURL(job.group, job.id)">{{job.name}}</router-link></td>
<td>
<span v-if="!job.latestStatus">-</span>
<span v-else>{{formatLatest(job.latestStatus)}}</span>
<br/>
<span>{{formatNextRunTime(job.nextRunTime)}}</span>
</td>
<td :class="{error: job.latestStatus && !job.latestStatus.success}">
<span v-if="!job.latestStatus">-</span>
<router-link v-else :to="'/log/'+job.latestStatus.refLogId">{{$L(job.latestStatus.success ? 'successed' : 'failed')}}</router-link> |
<router-link :to="{path: 'log', query: {latest:true, ids: job.id}}">latest</router-link> |
<a href="#" :title="$L('click to select a node and re-execute job')" v-on:click.prevent="showExecuteJobModal(job.name, job.group, job.id)"><i class="icon repeat"></i></a>
</td>
</tr>
<div class="ui fitted checkbox" v-show="batched">
<input type="checkbox" :value="job.group+'/'+job.id" v-model="batchIds"><label></label>
</div>
</td>
<td class="center aligned"><i ref="ruletip" :data-html="showTimer(job.rules)" class="icon" v-bind:class="{pause: job.pause, play: !job.pause, green: !job.pause}"></i></td>
<td>{{job.group}}</td>
<td>{{job.user && job.user.length > 0 ? job.user : '-'}}</td>
<td><router-link :to="buildEditJobURL(job.group, job.id)">{{job.name}}</router-link></td>
<td>
<span v-if="!job.latestStatus">-</span>
<span v-else>{{formatLatest(job.latestStatus)}}</span>
<br/>
<span>{{formatNextRunTime(job.nextRunTime)}}</span>
</td>
<td :class="{error: job.latestStatus && !job.latestStatus.success}">
<span v-if="!job.latestStatus">-</span>
<router-link v-else :to="'/log/'+job.latestStatus.refLogId">{{$L(job.latestStatus.success ? 'successed' : 'failed')}}</router-link> |
<router-link :to="{path: 'log', query: {latest:true, ids: job.id}}">latest</router-link> |
<a href="#" :title="$L('click to select a node and re-execute job')" v-on:click.prevent="showExecuteJobModal(job.name, job.group, job.id)"><i class="icon repeat"></i></a>
</td>
</tr>
<tr class="cmd-box" ><td colspan="7">{{job.cmd}}</td></tr>
</template>
</tbody>
</table>
<ExecuteJob ref="executeJobModal"/>
Expand All @@ -100,7 +105,7 @@ export default {
jobs: []
}
},

mounted: function(){
this.fillParams();
var vm = this;
Expand Down Expand Up @@ -157,6 +162,7 @@ export default {
vm.jobs = resp;
vm.$nextTick(()=>{
$(vm.$el).find('table .ui.dropdown').dropdown();
$(vm.$refs.ruletip).popup();
});
}).do();
},
Expand Down Expand Up @@ -194,7 +200,7 @@ export default {

formatExecResult: function(st){
if (!st) return '-';
return
return
},

formatLatest: function(latest){
Expand All @@ -209,6 +215,13 @@ export default {
this.$refs.executeJobModal.show(jobName, jobGroup, jobId);
},

showTimer: function(rules){
var timers = rules.map(function (rule) {
return rule.timer;
});
return timers.join("\n");
},

batch: function(op){
switch(op) {
case 'start': break;
Expand Down
28 changes: 16 additions & 12 deletions web/ui/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ var restApi = new Rest('/v1/', (msg) => {
bus.$emit('goLogin')
}
});
var loadNodes = function(resolve) {
restApi.GET('nodes').onsucceed(200, (resp) => {
var nodes = {};
for (var i in resp) {
nodes[resp[i].id] = resp[i];
}
store.commit('setNodes', nodes);
if(typeof resolve == "function"){
resolve();
}
}).do();
}

Vue.use((Vue, options) => {
Vue.prototype.$rest = restApi;
}, null);
Expand All @@ -60,6 +73,8 @@ Vue.use((Vue) => {
}
Vue.use(Config);
bus.$emit('conf_loaded', resp);
loadNodes();

}).onfailed((data, xhr) => {
var msg = data ? data : xhr.status + ' ' + xhr.statusText;
bus.$emit('error', msg);
Expand Down Expand Up @@ -132,18 +147,7 @@ var initConf = new Promise((resolve) => {
restApi.GET('configurations').onsucceed(200, (resp) => {
Vue.use((Vue) => Vue.prototype.$appConfig = resp);
bus.$emit('conf_loaded', resp);

var loadNodes = function() {
restApi.GET('nodes').onsucceed(200, (resp) => {
var nodes = {};
for (var i in resp) {
nodes[resp[i].id] = resp[i];
}
store.commit('setNodes', nodes);
resolve();
}).do();
}
loadNodes();
loadNodes(resolve);
setInterval(loadNodes, 60*1000);

}).onfailed((data, xhr) => {
Expand Down