Ejemplo n.º 1
0
func (w *Worker) handleRequest(writer http.ResponseWriter, request *http.Request) {
	contentType := request.Header.Get("Content-Type")
	if contentType == "" {
		contentType = w.defaultContentType
	}
	var unmarshaller gototo.UnmarshalFunction
	if unmarshaller = w.unmarshalMap[contentType]; unmarshaller == nil {
		unmarshaller = w.unmarshal
		contentType = w.defaultContentType
	}
	defer w.handlePanic(writer, contentType)
	body, err := ioutil.ReadAll(request.Body)
	if err != nil {
		w.writeResponse(writer, contentType, gototo.CreateErrorResponse(fmt.Errorf("Failed to read request body: %s", err)), 500)
		return
	}

	requestData, err := unmarshaller(body)
	if err != nil {
		w.writeResponse(writer, contentType, gototo.CreateErrorResponse(fmt.Errorf("Failed to unmarshal request: %s", err)), 500)
		return
	}
	workerFunction := w.registeredWorkerFunctions[requestData.Method]
	if workerFunction == nil {
		w.writeResponse(writer, contentType, gototo.CreateErrorResponse(fmt.Errorf("No method found: %s", requestData.Method)), 404)
		return
	}
	startTime := time.Now()
	result := workerFunction(requestData.Parameters)
	if w.logMetrics {
		log.Println("Request", requestData.Method, "finished in", time.Now().Sub(startTime))
	}
	w.writeResponse(writer, contentType, result, 200)
}
Ejemplo n.º 2
0
func TestCall(t *testing.T) {
	tcpAddr, _ := net.ResolveTCPAddr("tcp", ":0")
	l, err := net.ListenTCP("tcp", tcpAddr)
	if err != nil {
		t.Fatal("Failed to create TCP listener:", err)
	}
	tcpAddr = l.Addr().(*net.TCPAddr)
	err = l.Close()
	if err != nil {
		t.Fatal("Failed to create TCP listener:", err)
	}
	worker := New(fmt.Sprintf("tcp://*:%d", tcpAddr.Port), 10)
	worker.SetLogMetrics(true)
	var _ gototo.Worker = worker
	worker.RegisterWorkerFunction("test_func", worker.MakeWorkerFunction(func(i *SampleValidatedType) *gototo.Response {
		if i.String != "fail" {
			return gototo.CreateSuccessResponse(i)
		}
		return gototo.CreateErrorResponse(gototo.NewCodedError("Empty string!", 42))
	}))
	worker.RegisterWorkerFunction("slow_test_func", worker.MakeWorkerFunction(func(i *WaitRequest) *gototo.Response {
		time.Sleep(i.Timeout)
		return gototo.CreateSuccessResponse(i)
	}))
	err = worker.Start()
	if err != nil {
		t.Fatal("Failed to start worker:", err)
	}
	time.Sleep(100 * time.Millisecond)
	defer worker.Stop()
	addr := fmt.Sprintf("tcp://127.0.0.1:%d", tcpAddr.Port)
	connection := NewConnection(addr)
	var _ gototo.WorkerConnection = connection
	connection.RegisterResponseType("test_func", &SampleValidatedType{}, true)
	connection.RegisterResponseType("slow_test_func", &WaitRequest{}, true)
	connection.RegisterDefaultOptions("slow_test_func", &gototo.RequestOptions{Timeout: 100 * time.Millisecond, RetryCount: 3})
	err = connection.Start()
	if err != nil {
		t.Fatal("Failed to start connection:", err)
	}
	err = connection.Disconnect(addr)
	if err != nil {
		t.Fatal("Failed to disconnect:", err)
	}
	if len(connection.GetEndpoints()) > 0 {
		t.Fatal("Expected no connections")
	}
	err = connection.Connect(addr)
	if err != nil {
		t.Fatal("Failed to reconnect:", err)
	}
	if len(connection.GetEndpoints()) != 1 {
		t.Fatal("Expected one connections")
	}
	err = connection.SetEndpoints()
	if err != nil {
		t.Fatal("Failed to disconnect:", err)
	}
	if len(connection.GetEndpoints()) > 0 {
		t.Fatal("Expected no connections")
	}
	err = connection.SetEndpoints(addr)
	if err != nil {
		t.Fatal("Failed to reconnect:", err)
	}
	if len(connection.GetEndpoints()) != 1 {
		t.Fatal("Expected one connections")
	}
	err = connection.Connect(addr)
	if err != nil {
		t.Fatal("Failed to reconnect:", err)
	}
	if len(connection.GetEndpoints()) != 1 {
		t.Fatal("Expected one connections")
	}
	defer connection.Stop()
	resp, err := connection.Call("test_func", &SampleValidatedType{String: "test request string"})
	if err != nil {
		t.Fatal("Failed to decode response:", err)
	}
	if svt, ok := resp.(*SampleValidatedType); !ok {
		t.Fatalf("Bad response: %#v\n", resp)
	} else if svt.String != "test request string" {
		t.Fatalf("Bad response: %#v\n", resp)
	}
	resp, err = connection.Call("test_func", &SampleValidatedType{String: ""})
	if err == nil {
		t.Fatalf("Expected error: %#v %#v\n", resp, err)
	} else {
		if responseError, ok := err.(*gototo.ResponseError); !ok {
			t.Fatalf("Expected *ResponseError: %#v\n", err)
		} else if responseError.Error() != "Validation failed: Empty String field" {
			t.Fatalf("Expected 'Validation failed: Empty String field': %#v\n", err)
		} else if responseError.Code() != gototo.CodeValidationFailed {
			log.Printf("%#v", responseError)
			t.Fatalf("Expected validation failed code, found %d", responseError.Code())
		}
	}
	resp, err = connection.Call("test_func", &SampleValidatedType{String: "fail"})
	if err == nil {
		t.Fatalf("Expected error: %#v %#v\n", resp, err)
	} else {
		if responseError, ok := err.(*gototo.ResponseError); !ok {
			t.Fatalf("Expected *ResponseError: %#v\n", err)
		} else if responseError.Error() != "Empty string!" {
			t.Fatalf("Expected 'Empty string!': %#v\n", err)
		} else if responseError.Code() != 42 {
			t.Fatalf("Expected error code 42, found %d", responseError.Code())
		}
	}
	resp, err = connection.Call("slow_test_func", &WaitRequest{Timeout: 200 * time.Millisecond})
	if err != nil {
		t.Error("Unexpected response error:", err)
	}
	resp, err = connection.Call("slow_test_func", &WaitRequest{Timeout: 1 * time.Second})
	if err != gototo.ErrTimeout {
		t.Error("Expected timeout, found:", err, resp)
	}
}