func()

in openwhisk/runHandler.go [68:149]


func (ap *ActionProxy) runHandler(w http.ResponseWriter, r *http.Request) {
	if ap.proxyMode == ProxyModeNone {
		ap.doRun(w, r)
		return
	}

	if ap.proxyMode == ProxyModeClient {
		ap.ForwardRunRequest(w, r)
		return
	}

	if ap.proxyMode == ProxyModeServer {
		// parse the request
		body, err := io.ReadAll(r.Body)
		defer r.Body.Close()
		if err != nil {
			sendError(w, http.StatusBadRequest, fmt.Sprintf("Error reading request body: %v", err))
			return
		}

		var runRequest runRequest
		err = json.NewDecoder(bytes.NewReader(body)).Decode(&runRequest)
		if err != nil {
			sendError(w, http.StatusBadRequest, fmt.Sprintf("Error decoding run body: %v", err))
			return
		}

		if runRequest.ActionCodeHash == "" {
			sendError(w, http.StatusBadRequest, "Action code hash not provided from client")
			return
		}
		innerActionProxy, ok := ap.serverProxyData.actions[runRequest.ActionCodeHash]
		if !ok {
			Debug("Action hash %s not found in server proxy data", runRequest.ActionCodeHash)
			sendError(w, http.StatusNotFound, "Action not found in remote runtime. Check logs for details.")
			return
		}

		// Enqueue the request to be processed by the inner proxy one at a time
		responseChan := make(chan *ServerRunResponseChanPayload)

		innerActionProxy.runRequestQueue <- &remoteRunChanPayload{runRequest: &runRequest, respChan: responseChan}

		res := <-responseChan
		if res.err != nil {
			sendError(w, res.status, res.err.Error())
			return
		}

		// write response
		// turn response struct into json
		responsePayload, err := json.Marshal(res.runResp)
		if err != nil {
			sendError(w, http.StatusInternalServerError, fmt.Sprintf("Error marshalling response: %v", err))
			return
		}

		// write response
		w.Header().Set("Content-Type", "application/json")
		w.Header().Set("Content-Length", fmt.Sprintf("%d", len(responsePayload)))
		numBytesWritten, err := w.Write(responsePayload)

		// handle writing errors
		if err != nil {
			Debug("(remote) Error writing response: %v", err)
			sendError(w, http.StatusInternalServerError, fmt.Sprintf("Error writing response: %v", err))
			return
		}
		if numBytesWritten < len(responsePayload) {
			Debug("(remote) Only wrote %d of %d bytes to response", numBytesWritten, len(responsePayload))
			sendError(w, http.StatusInternalServerError, fmt.Sprintf("Only wrote %d of %d bytes to response", numBytesWritten, len(responsePayload)))
			return
		}

		// flush output if possible
		if f, ok := w.(http.Flusher); ok {
			f.Flush()
		}

		close(responseChan)
	}
}