Exemplo n.º 1
0
func (c MasterApplication) Attempt() revel.Result {
	w := new(CompileRunResult)

	if err := json.NewDecoder(c.Request.Body).Decode(w); err != nil {
		stats.TRACE.Println("Failed to decode attempt ", err)
		return c.RenderJson(map[string]interface{}{
			"status": "error",
			"data":   "Failed to parse request",
		})
	}

	//revel.TRACE.Println("/here...")

	for _, ws := range w.Result {
		ws.RequestEndTime = time.Now()
		stats.LogTime("Master", "Submission", ws.RequestStartTime, ws.RequestEndTime)
	}

	server.CreateAttemptWithStates(w.Result)

	return c.RenderJson(map[string]interface{}{
		"status": "success",
		"data":   "Attempt logged",
	})
}
Exemplo n.º 2
0
func runBuildFile(s *WorkerState) {
	var stdout, stderr bytes.Buffer

	s.CompileStartTime = time.Now()
	_, err := runOutput(CompileTimeout,
		nil, /* env */
		&stdout,
		&stderr,
		filepath.Dir(s.BuildFileName),
		[]string{s.BuildFileName},
	)
	s.CompileEndTime = time.Now()

	stats.LogTime("Worker", "CompileTime", s.CompileStartTime, s.CompileEndTime)

	s.CompileStdout = string(stdout.Bytes())
	s.CompileStderr = string(stderr.Bytes())

	if err != nil {
		switch err.(type) {
		case TimeoutError:
			s.TimeoutError = true
			s.TimeoutValue = err.(TimeoutError).Timeout
			stats.Incr("Worker", "RunTimeout")
			panic("Failed to compile program")
			return
		}
	}
	if err != nil ||
		!FileExists(filepath.Join(s.TemporaryDirectory, s.ExecutableFileName)) {
		s.CompilationFailed = true
		stats.Incr("Worker", "CompilationFailed")
		panic("Failed to compile program")
	}
}
Exemplo n.º 3
0
func runProgram(s *WorkerState) {
	var stdout, stderr bytes.Buffer

	stats.Incr("Worker", "Run")

	conf := s.MachineProblemConfig

	outputFileExtension := func() string {
		if conf.OutputType == "image" {
			return "ppm"
		} else {
			return "raw"
		}
	}

	getInputs := func() []string {
		if s.DatasetId < 0 {
			return []string{"none"}
		} else {
			datasetConfig := conf.Datasets[s.DatasetId]
			inputs := make([]string, len(datasetConfig.Input))
			for i, input := range datasetConfig.Input {
				inputs[i] = filepath.Join(s.MachineProblemDirectory, "data", input)
			}
			return inputs
		}
	}

	getOutput := func() string {
		if s.DatasetId < 0 {
			return "none"
		} else {
			datasetConfig := conf.Datasets[s.DatasetId]
			output := datasetConfig.Output
			return filepath.Join(s.MachineProblemDirectory, "data", output)
		}
	}

	s.UserOutput = filepath.Join(s.TemporaryDirectory, "output."+outputFileExtension())

	runCommand := []string{
		filepath.Join(s.TemporaryDirectory, s.ExecutableFileName),
		"-i ", strings.Join(getInputs(), ","),
		//"-o ", s.UserOutput,
		"-e ", getOutput(),
		"-t ", conf.OutputType,
	}

	s.RunStartTime = time.Now()
	_, err := runOutput(RuntimeTimeout,
		nil, /* env */
		&stdout,
		&stderr,
		filepath.Dir(s.BuildFileName),
		runCommand,
	)
	s.RunEndTime = time.Now()

	stats.LogTime("Worker", "RunTime", s.RunStartTime, s.RunEndTime)

	s.RunStdout = string(stdout.Bytes())
	s.RunStderr = string(stderr.Bytes())

	removeInternalData := func(s string) string {
		ss := strings.Split(s, seperator)
		return ss[0]
	}

	switch err.(type) {
	case TimeoutError:
		revel.TRACE.Println("Terminated....")
		s.TimeoutError = true
		s.TimeoutValue = err.(TimeoutError).Timeout
		stats.Incr("Worker", "RunTimeout")
		panic("Failed to run program")
	}

	if strings.Contains(s.RunStderr, "<<SANDBOXED>>") {
		s.Sandboxed = true
		s.SandboxKeyword = "Program sandboxed because of use of " +
			removeInternalData(strings.TrimPrefix(s.RunStdout, "<<SANDBOXED>>::")) +
			" keyword."
		stats.Log("Worker", "RunSandboxed", s.SandboxKeyword)
		panic("Failed to run program")
	} else if strings.Contains(s.RunStderr, "<<MEMORY>>") {
		s.RunFailed = true
		s.RunStdout = ""
		s.RunStderr = "Program teminated because it is allocating too much memory."
		stats.Incr("Worker", "MemoryLimit")
		panic("Failed to run program")
	} else if err != nil {
		s.RunFailed = true
		s.RunStdout = removeInternalData(s.RunStdout)
		stats.Incr("Worker", "RunFailed")
		panic("Failed to run program")
	}

	ss := strings.Split(s.RunStdout, seperator)
	s.RunStdout = ss[0]

	var wbData InternalCData

	normalizeString := func(s string) string {
		res := s
		if !utf8.ValidString(s) {
			v := make([]rune, 0, len(s))
			for i, r := range s {
				if r == utf8.RuneError {
					if _, size := utf8.DecodeRuneInString(s[i:]); size == 1 {
						continue
					}
				}
				v = append(v, r)
			}
			res = string(v)
		}
		return res
	}

	err = json.Unmarshal([]byte(normalizeString(ss[1])), &wbData)
	if err != nil {
		stats.Incr("Worker", "InternalDataReadError")
		s.RunFailed = true
		s.RunStdout = s.RunStdout
		s.RunStderr = "Failed to read program output. Make sure you do not have special characters in your code."
		stats.Log("Worker", "Error", "Failed to read internal data  "+fmt.Sprint(err))
		return
	}

	if s.DatasetId < 0 {
		wbData.SolutionExists = false
		wbData.Solution.CorrectQ = true
		wbData.Solution.Message = "No solution expected."
	}

	s.SolutionCorrect = wbData.Solution.CorrectQ
	s.SolutionMessage = wbData.Solution.Message
	s.InternalCData = wbData

	if !s.SolutionCorrect {
		stats.Log("Worker", "IncorrectSolution", 1)
	} else {
		stats.Log("Worker", "CorrectSolution", 1)
	}
}