🎨 不通过 timeout 命令控制执行超时
This commit is contained in:
parent
e952c8fa09
commit
9a16c9214f
|
@ -22,6 +22,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/session"
|
"github.com/b3log/wide/session"
|
||||||
|
@ -51,7 +52,7 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var cmd *exec.Cmd
|
var cmd *exec.Cmd
|
||||||
if conf.Docker {
|
if conf.Docker {
|
||||||
fileName := filepath.Base(filePath)
|
fileName := filepath.Base(filePath)
|
||||||
cmd = exec.Command("timeout", "-s", "9", "5", "docker", "run", "--rm", "--cpus", "0.1", "-v", filePath+":/"+fileName, conf.DockerImageGo, "/"+fileName)
|
cmd = exec.Command("docker", "run", "--rm", "--cpus", "0.1", "-v", filePath+":/"+fileName, conf.DockerImageGo, "/"+fileName)
|
||||||
} else {
|
} else {
|
||||||
cmd = exec.Command(filePath)
|
cmd = exec.Command(filePath)
|
||||||
curDir := filepath.Dir(filePath)
|
curDir := filepath.Dir(filePath)
|
||||||
|
@ -88,6 +89,9 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done := make(chan error)
|
||||||
|
go func() { done <- cmd.Wait() }()
|
||||||
|
|
||||||
channelRet["pid"] = cmd.Process.Pid
|
channelRet["pid"] = cmd.Process.Pid
|
||||||
|
|
||||||
// add the process to user's process set
|
// add the process to user's process set
|
||||||
|
@ -103,6 +107,7 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rid := rand.Int()
|
||||||
go func(runningId int) {
|
go func(runningId int) {
|
||||||
defer util.Recover()
|
defer util.Recover()
|
||||||
|
|
||||||
|
@ -147,25 +152,26 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
wsChannel.Refresh()
|
wsChannel.Refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}(rid)
|
||||||
|
|
||||||
cmd.Wait()
|
after := time.After(5 * time.Second)
|
||||||
|
|
||||||
// remove the exited process from user's process set
|
|
||||||
Processes.Remove(wSession, cmd.Process)
|
|
||||||
|
|
||||||
channelRet["cmd"] = "run-done"
|
channelRet["cmd"] = "run-done"
|
||||||
// timeout: https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html
|
select {
|
||||||
exitCode := cmd.ProcessState.ExitCode()
|
case <-after:
|
||||||
if 124 == exitCode || 125 == exitCode || 137 == exitCode {
|
cmd.Process.Kill()
|
||||||
|
|
||||||
channelRet["output"] = "<span class='stderr'>run program timeout in 5s</span>\n"
|
channelRet["output"] = "<span class='stderr'>run program timeout in 5s</span>\n"
|
||||||
} else {
|
case <-done:
|
||||||
channelRet["output"] = "\n<span class='stderr'>run program complete</span>\n"
|
channelRet["output"] = "\n<span class='stderr'>run program complete</span>\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Processes.Remove(wSession, cmd.Process)
|
||||||
|
logger.Debugf("User [%s, %s] done running [id=%d, file=%s]", wSession.UserId, sid, rid, filePath)
|
||||||
|
|
||||||
if nil != wsChannel {
|
if nil != wsChannel {
|
||||||
wsChannel.WriteJSON(&channelRet)
|
wsChannel.WriteJSON(&channelRet)
|
||||||
wsChannel.Refresh()
|
wsChannel.Refresh()
|
||||||
}
|
}
|
||||||
}(rand.Int())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopHandler handles request of stoping a running process.
|
// StopHandler handles request of stoping a running process.
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/b3log/wide/conf"
|
"github.com/b3log/wide/conf"
|
||||||
"github.com/b3log/wide/output"
|
"github.com/b3log/wide/output"
|
||||||
|
@ -52,7 +53,7 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var cmd *exec.Cmd
|
var cmd *exec.Cmd
|
||||||
if conf.Docker {
|
if conf.Docker {
|
||||||
fileName := filepath.Base(filePath)
|
fileName := filepath.Base(filePath)
|
||||||
cmd = exec.Command("timeout", "-s", "9", "5", "docker", "run", "--rm", "--cpus", "0.1", "-v", filePath+":/"+fileName, conf.DockerImageGo, "/"+fileName)
|
cmd = exec.Command("docker", "run", "--rm", "--cpus", "0.1", "-v", filePath+":/"+fileName, conf.DockerImageGo, "/"+fileName)
|
||||||
} else {
|
} else {
|
||||||
cmd = exec.Command(filePath)
|
cmd = exec.Command(filePath)
|
||||||
curDir := filepath.Dir(filePath)
|
curDir := filepath.Dir(filePath)
|
||||||
|
@ -90,6 +91,9 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done := make(chan error)
|
||||||
|
go func() { done <- cmd.Wait() }()
|
||||||
|
|
||||||
channelRet["pid"] = cmd.Process.Pid
|
channelRet["pid"] = cmd.Process.Pid
|
||||||
|
|
||||||
// add the process to user's process set
|
// add the process to user's process set
|
||||||
|
@ -105,6 +109,7 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rid := rand.Int()
|
||||||
go func(runningId int) {
|
go func(runningId int) {
|
||||||
defer util.Recover()
|
defer util.Recover()
|
||||||
|
|
||||||
|
@ -149,23 +154,26 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
wsChannel.Refresh()
|
wsChannel.Refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}(rid)
|
||||||
|
|
||||||
cmd.Wait()
|
after := time.After(5 * time.Second)
|
||||||
|
|
||||||
// remove the exited process from user's process set
|
|
||||||
output.Processes.Remove(wSession, cmd.Process)
|
|
||||||
|
|
||||||
channelRet["cmd"] = "run-done"
|
channelRet["cmd"] = "run-done"
|
||||||
// timeout: https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html
|
select {
|
||||||
exitCode := cmd.ProcessState.ExitCode()
|
case <-after:
|
||||||
if 124 == exitCode || 125 == exitCode || 137 == exitCode {
|
cmd.Process.Kill()
|
||||||
|
|
||||||
channelRet["output"] = "\nrun program timeout in 5s\n"
|
channelRet["output"] = "\nrun program timeout in 5s\n"
|
||||||
|
case <-done:
|
||||||
|
channelRet["output"] = "\nrun program complete\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output.Processes.Remove(wSession, cmd.Process)
|
||||||
|
logger.Debugf("User [%s, %s] done running [id=%d, file=%s]", wSession.UserId, sid, rid, filePath)
|
||||||
|
|
||||||
if nil != wsChannel {
|
if nil != wsChannel {
|
||||||
wsChannel.WriteJSON(&channelRet)
|
wsChannel.WriteJSON(&channelRet)
|
||||||
wsChannel.Refresh()
|
wsChannel.Refresh()
|
||||||
}
|
}
|
||||||
}(rand.Int())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopHandler handles request of stoping a running process.
|
// StopHandler handles request of stoping a running process.
|
||||||
|
|
Loading…
Reference in New Issue