Giovanni Cardamone
Giovanni Cardamone

Reputation: 197

Restart task if is already running

i have this task that is server for my application:

"tasks": [
    {
        "label": "f1",
        "type": "shell",
        "command": "gunicorn",
        "args": [
            "main:api"
        ],
        "isBackground": true,
    },
]

is mapped on key "F1", now, if this task is active, when i press F1, i want to kill it and start again. So i don't have to press CTRL-C each time i write new function.

How i can implement this behaivor? - Thanks

Upvotes: 17

Views: 28401

Answers (9)

Kauan
Kauan

Reputation: 51

Faced a similar problem creating tasks that would open a monitor terminal (therefore would not close at the end of the execution, because there would be no end of execution). To go around this issue, I assigned the same keybind I had for running the task to the Restart Task command, but only if there was any task running, adding this to my keybindings.json:

    {
        "key": "ctrl+shift+b", // replace with your running task keybind
        "command": "workbench.action.tasks.restartTask",
        "when": "taskRunning"
    },

It may not be the best approach, since it will assume you want to restart a task if any task is running, but if there is only one task in your workspace, it'll do.

Upvotes: 5

ArtemGr
ArtemGr

Reputation: 12567

Example of AutoHotkey script that would press the Restart Task button after issuing a Ctrl+B.

Left(lx, ly, ls, lt)
{
  MouseMove, lx, ly, ls
  Send {LButton down}
  Sleep lt
  Send {LButton up}
  Sleep 31
}

#If WinActive("ahk_exe Code.exe")

; Win+B to automatically restart the build task
#b::
  MouseGetPos mx, my
  Send ^b
  Sleep 314
  WinGetPos, wx, wy, w, h, ahk_exe Code.exe
  xx := w - 321
  yy := h - 123
  ;ToolTip wx= %wx% wy= %wy% w= %w% h= %h% xx= %xx% yy= %yy%
  ImageSearch, x, y, %xx%, 1, %w%, %h%, *123 c:\VSCode-RestartTask.png
  if (ErrorLevel = 0)
  {
    ;ToolTip x= %x% y= %y%
    Left(x, y, 2, 123)
  }
  MouseMove, mx, my, 2
  ToolTip
  Return

Example of the picture used as VSCode-RestartTask.png. Though one would likely need to make a fresh capture in order to account for system-specific scaling, etc.

enter image description here

p.s. Another option is to bind the "Terminal: Kill the Active Terminal Instance" Keyboard Shortcut to a separate key and to press them both in a sequence.

I have it bound to Ctrl+W

{
  "key": "ctrl+w",
  "command": "workbench.action.terminal.kill"
},

hence the restart script is

#If WinActive("ahk_exe Code.exe")

#b::
  Send ^w
  Sleep 31
  Send ^b
  Return

Upvotes: -1

Quer
Quer

Reputation: 492

Inspired by @Luiz Felipe's answer:

Goal: To restart a task without clicking the prompt

Process: Determine the task you need to terminate, if determined kill the task, then run the process

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "kill-npm-first",
      "type": "shell",
      "command": "PID=( $(ps aux | grep node || true | awk '{print $2}') ); kill -9 PID \"${PID[2]}\" || true && exit 0;"
    },
    {
        "label": "ns",
        "type": "npm",
        "problemMatcher": [],
        "script": "start",
        "runOptions": {
          "instanceLimit": 999
        },
        "group": {
          "kind": "build",
          "isDefault": true
        },
        "dependsOn": ["kill-npm-first"],
        "dependsOrder": "sequence",
        "detail": "node --max-old-space-size=1536 --preserve-symlinks bin/www"
    }
  ]
}

Output:

  • If task ns (ns - npm start) is not yet running it will spawn a new task

  • If any task named ns, spawn a new task window

  • It doesn't close the first task window

  • Successfully terminates the first task

  • Creates 2 terminal windows in vscode (if there's one instance running)

  • If there are two existing task windows, it will rerun the task interchangeably (eg. two tasks ns are running, execute task ns again, and it will rerun the script in the first task window and consecutively)

Feel free to comment if you see any improvement in this script.

Upvotes: 1

Luiz Felipe
Luiz Felipe

Reputation: 1189

I wanted to restart my task always without getting the annoying prompt, it was either there's a way to do it only by using the linux shell or I will make an extension for vscode.

First, lets think about the easy path (probably), using the shell. How would we proceed to always restart a hanging script if we only had xterms ? We try to find the process by the command line and kill them, then we start the newer one.

Lets say we are debugging a shell script named stages.sh.

ps -A -o pid=,cmd= | grep stages.sh | grep -P -o '^[ ](\d+)'| xargs kill -KILL

That will kill all previous instances. But that's no good, we can do a neat trick by using the internal exec to fork the bash process with a different process name.

exec -a my-task bash ./stages.sh
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
monad     271915  0.0  0.0  11324  5912 pts/1    Ss+  Jul20   0:00 /usr/bin/bash
monad     272177  0.0  0.0   9420  5400 pts/2    Ss+  Jul20   0:00 /usr/bin/bash
monad     342891  0.0  0.6 4885572 112040 pts/6  Ssl+ Jul21   1:30 /usr/bin/pwsh-preview -NoProfile -EncodedCommand SQBtAHAAbwByAHQALQBNAG8AZAB1AGwAZQAgACcALwBoAG8AbQBlAC8AbQBvAG4AYQBkAC8ALgB2AHMAYwBvAGQAZQAtAHMAZQByAHYAZQB
monad     544486  0.5  2.2 8948900 375132 pts/7  Ssl+ 10:31   2:01 buckd -Dbuck.is_buckd=true -Dbuck.buckd_launch_time_nanos=672292609941292 -Dfile.encoding=UTF-8 -XX:MaxGCPauseMillis=15000 -XX:SoftRefLRUPolicyMSPerMB=0 -XX
monad     588089  0.0  0.0   9608  6360 pts/3    Ss   16:11   0:00 /usr/bin/bash
monad     588182  0.0  0.0   7076  3632 pts/3    S+   16:12   0:00 my-task ./stages.sh
monad     604842  0.0  0.0   7076   404 pts/3    S+   16:40   0:00 my-task ./stages.sh
monad     604843  0.0  0.0   5552   740 pts/3    S+   16:40   0:00 cat
monad     604844  0.0  0.0   5712   676 pts/3    S+   16:40   0:00 xargs echo --config-file
monad     604936  0.1  0.0   9608  6304 pts/9    Ss   16:40   0:00 /usr/bin/bash
monad     604986  0.0  0.0  10064  3448 pts/9    R+   16:41   0:00 ps au

Nice, now its easier to find the correct task to kill. And now pkill can work too.

pkill -KILL -f my-task

Now that we found a way to restart a shell task, we just need to make vscode task script. We know that if the shell process dies, the task ends and vscode reuse the terminal, we also know that we forked the process, so if the child dies, the parent bash dies too.

So we get

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "kill-buck",
            "type": "shell",
            "command": "pkill -KILL -f vscode-task && exit 0"
        },
        {
            "label": "buck",
            "type": "shell",
            "command": "exec -a vscode-task bash ${workspaceFolder}/stages.sh",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            },
        }
    ]
}

That creates the task and we can manually kill it with ctrl+shift+p and run task kill-buck, but that's no good, we can do better.

Its possible to serialize the tasks to run in sequence.

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "kill-buck",
            "type": "shell",
            "command": "pkill -KILL -f vscode-task && exit 0"
        },
        {
            "label": "buck",
            "type": "shell",
            "command": "exec -a vscode-task bash ${workspaceFolder}/stages.sh",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "dependsOn": ["kill-buck"],
            "dependsOrder": "sequence"
        }
    ]
}

That's better, but we still have the pesky warning. So, finally we add one last trick to get rid of it.

There's a special property on runOptions called instanceLimit to set up the number of concurrent runs we allow.

As we are starting a new run while we are leaving the other running and because we are going to kill them any way, we can trick vscode into thinking that we are going to have more than 1 instance. But as we kill all the previous others before by using another task, the bash process will die and free the same task to be used again, there will be only one instance, and vscode will reuse the same window.

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "kill-buck",
            "type": "shell",
            "command": "pkill -KILL -f vscode-task && exit 0"
        },
        {
            "label": "buck",
            "type": "shell",
            "command": "exec -a vscode-task bash ${workspaceFolder}/stages.sh",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "runOptions": {
                "instanceLimit": 999
            },
            "dependsOn": ["kill-buck"],
            "dependsOrder": "sequence"
        }
    ]
}

And that does what we wanted.

Upvotes: 2

Felix Orinda
Felix Orinda

Reputation: 743

There are two ways I know of

  1. First on the output area in vscode right click on the empty area and you'll have a window with an oprion to stop the code run
  2. Setting up the vscode code runner to run in terminal

Code running initially without stopping

Open the settings window and search for run in terminal Settings window

On the checkbox Code-runner:Run In Terminal ensure the checkbox is checked Checked checkbox

Close the settings window and run your code again. If it does't take effect reload or restart your vscode

You should see something like this when you run your code again Running in terminal safe

Your code now runs in the terminal and you can easily terminate using CTRL + C

Upvotes: 1

Vikas Vitekari
Vikas Vitekari

Reputation: 1

make sure that u are running code in terminal rather than output section for that

  1. go to settings
  2. go to extension
  3. Run configuration 4.(scroll little bit ) u find Run in terminal
  4. check that box close vs code and run the program again hope it helps enjoy coding

Upvotes: 0

David S Lee
David S Lee

Reputation: 1957

enter image description here

in the output area you can "Stop Code Run"

Upvotes: 4

Chandra Shekhar
Chandra Shekhar

Reputation: 617

As per Visual Studio Code Version 1.39.0 , You can right click the Output Area and choose

"Stop Code Run"

. Hope this is what you are looking for. Thanks

Upvotes: 11

BoDeX
BoDeX

Reputation: 926

As suggested by @jahuuar, there's a command for this:

Open the command palette (CMD/CTRL + Shift + P or Menu>View>Command Palette) and type "restart", you'll see "Tasks: Restart Running Task". If that's what you are looking for (it will ask for the task to restart, even if there is only one... Oo), you can then map a keyboard shortcut to that command.

Upvotes: 19

Related Questions