From c099277b27d256cd3cbf65d95fd8fb0ea1cca4e4 Mon Sep 17 00:00:00 2001 From: MaMe82 Date: Mon, 29 Oct 2018 17:46:15 +0100 Subject: [PATCH] webclient: Allow cancel for running HIDScript jobs --- service/rpc_server.go | 3 +- web_client/hvueCompHIDJobs.go | 42 ++++++++++++++--- web_client/hvueComponentsDialog.go | 14 ++++++ web_client/jsDataHandling.go | 11 ++++- web_client/mvuexGlobalState.go | 75 ++++++++++++++++++++++++++---- web_client/rpcClient.go | 18 +++++++ 6 files changed, 145 insertions(+), 18 deletions(-) diff --git a/service/rpc_server.go b/service/rpc_server.go index 5bd034e..754c3f6 100644 --- a/service/rpc_server.go +++ b/service/rpc_server.go @@ -604,8 +604,9 @@ func (s *server) HIDCancelAllScriptJobs(ctx context.Context, rEmpty *pb.Empty) ( func (s *server) HIDCancelScriptJob(ctx context.Context, sJob *pb.HIDScriptJob) (empty *pb.Empty, err error) { defer s.rootSvc.SubSysEvent.Emit(ConstructEventNotifyStateChange(common_web.STATE_CHANGE_EVT_TYPE_HID)) + empty = &pb.Empty{} job,err := s.rootSvc.SubSysUSB.HidScriptGetBackgroundJobByID(int(sJob.Id)) - if err != nil { return nil, err } + if err != nil { return empty, err } job.Cancel() return diff --git a/web_client/hvueCompHIDJobs.go b/web_client/hvueCompHIDJobs.go index e401c1f..2c9c7e6 100644 --- a/web_client/hvueCompHIDJobs.go +++ b/web_client/hvueCompHIDJobs.go @@ -35,6 +35,11 @@ func InitCompHIDJobs() { hvue.NewComponent( "hid-job-overview-item", hvue.Template(compHIDJobOverViewItemTemplate), + hvue.Method("cancel", func(vm *hvue.VM) { + job := &jsHidJobState{Object:vm.Get("job")} + println("Aborting job :", job.Id) + vm.Get("$store").Call("dispatch", VUEX_ACTION_CANCEL_HID_JOB, job.Id) + }), hvue.Computed("jobstate", func(vm *hvue.VM) interface{} { //fetch job and cast back to jobstate @@ -120,21 +125,46 @@ ScriptSource string `js:"textSource"` + + + + cancel HIDScript job {{ job.id }} + + + ` - //{ "evtype": 0, "vmId": 2, "jobId": 3, "hasError": false, "result": "null", "error": "", "message": "Script started", "time": "2018-07-30 04:56:42.297533 +0000 UTC m=+7625.097825001" } - compHIDJobOverviewTemplate = ` +//{ "evtype": 0, "vmId": 2, "jobId": 3, "hasError": false, "result": "null", "error": "", "message": "Script started", "time": "2018-07-30 04:56:42.297533 +0000 UTC m=+7625.097825001" } +compHIDJobOverviewTemplate = ` Running - Succeeded - - Failed - + + + + + + + + + + + + diff --git a/web_client/hvueComponentsDialog.go b/web_client/hvueComponentsDialog.go index 8fd4535..bc6be8a 100644 --- a/web_client/hvueComponentsDialog.go +++ b/web_client/hvueComponentsDialog.go @@ -171,6 +171,19 @@ const templateSelectStringModal = ` + + + + @@ -180,6 +193,7 @@ const templateSelectStringModal = ` + ` diff --git a/web_client/jsDataHandling.go b/web_client/jsDataHandling.go index 68af4d9..bd77e79 100644 --- a/web_client/jsDataHandling.go +++ b/web_client/jsDataHandling.go @@ -419,9 +419,16 @@ func (jl *jsHidJobStateList) UpdateEntry(id, vmId int64, hasFailed, hasSucceeded hvue.Set(jl.Jobs, key, j) } +func (jl *jsHidJobStateList) Clear() { + hvue.Set(jl,"jobs",O()) +} + + func (jl *jsHidJobStateList) DeleteEntry(id int64) { - jl.Jobs.Delete(strconv.Itoa(int(id))) //JS version - //delete(jl.Jobs, strconv.Itoa(int(id))) + key := strconv.Itoa(int(id)) + hvue.Delete(jl.Jobs, key) // vue reactive version + //jl.Jobs.Delete(key) //JS version + //delete(jl.Jobs, key) // go version } /* WiFi settings */ diff --git a/web_client/mvuexGlobalState.go b/web_client/mvuexGlobalState.go index 411563a..359a479 100644 --- a/web_client/mvuexGlobalState.go +++ b/web_client/mvuexGlobalState.go @@ -45,12 +45,16 @@ const ( //HIDScripts and jobs VUEX_ACTION_UPDATE_RUNNING_HID_JOBS = "updateRunningHidJobs" + VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS = "removeSucceededHidJobs" + VUEX_ACTION_REMOVE_FAILED_HID_JOBS = "removeFailedHidJobs" VUEX_ACTION_UPDATE_STORED_HID_SCRIPTS_LIST = "updateStoredHIDScriptsList" VUEX_ACTION_UPDATE_CURRENT_HID_SCRIPT_SOURCE_FROM_REMOTE_FILE = "updateCurrentHidScriptSourceFromRemoteFile" VUEX_ACTION_STORE_CURRENT_HID_SCRIPT_SOURCE_TO_REMOTE_FILE = "storeCurrentHidScriptSourceToRemoteFile" + VUEX_ACTION_CANCEL_HID_JOB = "cancelHIDJob" VUEX_MUTATION_SET_CURRENT_HID_SCRIPT_SOURCE_TO = "setCurrentHIDScriptSource" VUEX_MUTATION_SET_STORED_HID_SCRIPTS_LIST = "setStoredHIDScriptsList" + VUEX_MUTATION_DELETE_HID_JOB_ID = "deleteHIDJobID" //USBGadget VUEX_ACTION_DEPLOY_CURRENT_USB_SETTINGS = "deployCurrentUSBSettings" @@ -250,6 +254,52 @@ func actionUpdateAllStates(store *mvuex.Store, context *mvuex.ActionContext, sta } +func actionCancelHidJob(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState, jobID *js.Object) { + + + go func() { + id := uint32(jobID.Int()) + println("Cancel HIDScript job", id) + //fetch deployed gadget settings + err := RpcClient.CancelHIDScriptJob(defaultTimeout, id) + if err != nil { + println("Couldn't cancel HIDScript job", err) + return + } + + // ToDo: update HIDScriptJob list (should be done event based) + }() + + + return +} + +func actionRemoveSucceededHidJobs(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState) { + vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter + jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available + filtered := jobs.Call("filter", func(job *jsHidJobState) bool { + return job.HasSucceeded + }) + for i:=0; i< filtered.Length(); i++ { + job := &jsHidJobState{Object: filtered.Index(i)} + store.Commit(VUEX_MUTATION_DELETE_HID_JOB_ID, job.Id) + } + return +} + +func actionRemoveFailedHidJobs(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState) { + vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter + jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available + filtered := jobs.Call("filter", func(job *jsHidJobState) bool { + return job.HasFailed + }) + for i:=0; i< filtered.Length(); i++ { + job := &jsHidJobState{Object: filtered.Index(i)} + store.Commit(VUEX_MUTATION_DELETE_HID_JOB_ID, job.Id) + } + return +} + func actionStartEventListen(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState) { globalState.EventListenerShouldBeRunning = true go func() { @@ -878,6 +928,8 @@ func actionUpdateRunningHidJobs(store *mvuex.Store, context *mvuex.ActionContext return } + state.HidJobList.Clear() + for _, jobstate := range jobstates { println("updateing jobstate", jobstate) state.HidJobList.UpdateEntry(jobstate.Id, jobstate.VmId, false, false, "initial job state", "", time.Now().String(), jobstate.Source) @@ -1149,6 +1201,13 @@ func initMVuex() *mvuex.Store { mvuex.Mutation(VUEX_MUTATION_SET_EVENT_LISTENER_RUNNING, func(store *mvuex.Store, state *GlobalState, running *js.Object) { state.EventListenerRunning = running.Bool() }), + mvuex.Mutation(VUEX_MUTATION_DELETE_HID_JOB_ID, func(store *mvuex.Store, state *GlobalState, jobID *js.Object) { + id := jobID.Int() + state.HidJobList.DeleteEntry(int64(id)) + + }), + + mvuex.Action(VUEX_ACTION_UPDATE_ALL_STATES, actionUpdateAllStates), mvuex.Action(VUEX_ACTION_UPDATE_CURRENT_BLUETOOTH_CONTROLLER_INFORMATION, actionUpdateCurrentBluetoothControllerInformation), @@ -1208,6 +1267,11 @@ func initMVuex() *mvuex.Store { mvuex.Action(VUEX_ACTION_START_EVENT_LISTEN, actionStartEventListen), mvuex.Action(VUEX_ACTION_STOP_EVENT_LISTEN, actionStopEventListen), + mvuex.Action(VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS, actionRemoveSucceededHidJobs), + mvuex.Action(VUEX_ACTION_REMOVE_FAILED_HID_JOBS, actionRemoveFailedHidJobs), + mvuex.Action(VUEX_ACTION_CANCEL_HID_JOB, actionCancelHidJob), + + mvuex.Getter("triggerActions", func(state *GlobalState) interface{} { return state.TriggerActionList.TriggerActions }), @@ -1237,6 +1301,7 @@ func initMVuex() *mvuex.Store { }), mvuex.Getter("hidjobsSucceeded", func(state *GlobalState) interface{} { + println("Getter HID JOBS SUCCEEDED") vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available filtered := jobs.Call("filter", func(job *jsHidJobState) bool { @@ -1245,6 +1310,7 @@ func initMVuex() *mvuex.Store { return filtered }), + mvuex.Getter("storedWifiSettingsSelect", func(state *GlobalState) interface{} { selectWS := js.Global.Get("Array").New() for _, curS := range state.StoredWifiSettingsList { @@ -1270,18 +1336,9 @@ func initMVuex() *mvuex.Store { // Update WiFi state store.Dispatch(VUEX_ACTION_UPDATE_WIFI_STATE) - /* - // Update ethernet interface state (done by component) - store.Dispatch(VUEX_ACTION_UPDATE_ALL_ETHERNET_INTERFACE_SETTINGS) - */ - // propagate Vuex store to global scope to allow injecting it to Vue by setting the "store" option js.Global.Set("store", store) - /* - // Start Event Listening - state.EventProcessor.StartListening() - */ return store } diff --git a/web_client/rpcClient.go b/web_client/rpcClient.go index a4b013d..8ee5e22 100644 --- a/web_client/rpcClient.go +++ b/web_client/rpcClient.go @@ -29,6 +29,24 @@ func NewRpcClient(addr string) Rpc { return rcl } +func (rpc *Rpc) CancelHIDScriptJob(timeout time.Duration, jobID uint32) (err error) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + _,err = rpc.Client.HIDCancelScriptJob(ctx, &pb.HIDScriptJob{ + Id:jobID, + }) + return +} + +func (rpc *Rpc) CancelAllHIDScriptJobs(timeout time.Duration) (err error) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + _,err = rpc.Client.HIDCancelAllScriptJobs(ctx, &pb.Empty{}) + return +} + func (rpc *Rpc) GetStoredBluetoothSettingsList(timeout time.Duration) (ws []string, err error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel()