Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Feature which enable Connector to leverage Responses #4

Closed
wants to merge 3 commits into from
Closed

Conversation

Templum
Copy link

@Templum Templum commented Jan 20, 2019

Addresses Feature wishes from #2

Changes:

  • Invoke Signature changed from func (i *Invoker) Invoke(topicMap *TopicMap, topic string, message *[]byte) => func (i *Invoker) Invoke(topicMap *TopicMap, topic string, message *[]byte) (result map[string]*InvocationResult)

  • Renamed invokefunction to performInvocation and changed signature to performInvocation(c *http.Client, gwURL string, reader io.Reader) (err error, statusCode int, responseHeaders http.Header, responseBody *[]byte

  • If PrintResponse is true it will now also log the headers

  • Added Tests for Invoker covering some cases. Further logs show also the printing of header

Signed-off-by: Simon Pelczer [email protected]

results := target.Invoke(&topicMap, "Success", &body)

if len(results) != 0 {
t.Errorf("Expected 0 results recieved %d", len(results))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo "recieved" -> "received"

types/invoker.go Outdated
}

func invokefunction(c *http.Client, gwURL string, reader io.Reader) (*[]byte, int, error) {
func performInvocation(c *http.Client, gwURL string, reader io.Reader) (err error, statusCode int, responseHeaders http.Header, responseBody *[]byte) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to also return a struct (like InvokationResult above) instead of four individual response items?


if doErr != nil {
log.Printf("Unable to invoke from %s, error: %s\n", matchedFunction, doErr)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we're returning here too soon, i.e. if there's multiple matchedFuntions, others would not be executed if an error is thrown early. There could be an error with the receiving function (bug), others could be fine.

types/invoker.go Outdated
}

func invokefunction(c *http.Client, gwURL string, reader io.Reader) (*[]byte, int, error) {
func performInvocation(c *http.Client, gwURL string, reader io.Reader) (err error, statusCode int, responseHeaders http.Header, responseBody *[]byte) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making this a method on the invoker to avoid passing around objects multiple times.

types/invoker.go Outdated
}

func invokefunction(c *http.Client, gwURL string, reader io.Reader) (*[]byte, int, error) {
func performInvocation(c *http.Client, gwURL string, reader io.Reader) (err error, statusCode int, responseHeaders http.Header, responseBody *[]byte) {

httpReq, _ := http.NewRequest(http.MethodPost, gwURL, reader)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No error check here?

types/invoker.go Outdated
@@ -63,7 +73,7 @@ func invokefunction(c *http.Client, gwURL string, reader io.Reader) (*[]byte, in

res, doErr := c.Do(httpReq)
if doErr != nil {
return nil, http.StatusServiceUnavailable, doErr
return doErr, http.StatusServiceUnavailable, nil, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we distinct between HTTP error messages here, instead of always a "503"?

@Templum
Copy link
Author

Templum commented Jan 24, 2019

@embano1 Thanks for the input. I wanted originally to keep the same behaviour, however seeing you also raise those concerns convinced me to address them. Will push them in a new update.

* Using a Struct for return value for performInvocation
* No longer aborting requests on first error
* performInvocation is now method of Invoker
* Handled NewRequest error, altough this only happens when miss configured
Signed-off-by: Simon Pelczer <[email protected]>
* They now check that an failing function wont abort invocations
* They check that no invocation is performed for invalid messages
* They check error is only set when an error occurred
Signed-off-by: Simon Pelczer <[email protected]>
@alexellis
Copy link
Member

Hi both, please can we bear in mind any breaking changes for existing connectors (of which there are several, and not all are maintained by the project)

Alex


log.Printf("Invoke function: %s", matchedFunction)
type InvocationResponse struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InvocationResponse vs InvocationResult ?


matchedFunctions := topicMap.Match(topic)
for _, matchedFunction := range matchedFunctions {
func NewInvocationResult(statusCode int, body *[]byte, error error) *InvocationResult {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks redundant to me.


gwURL := fmt.Sprintf("%s/function/%s", i.GatewayURL, matchedFunction)
reader := bytes.NewReader(*message)
func NewInvocationResponse(statusCode int, body *[]byte, headers http.Header) *InvocationResponse {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it adds no value?

}

func invokefunction(c *http.Client, gwURL string, reader io.Reader) (*[]byte, int, error) {
func (i *Invoker) performInvocation(functionURL string, bodyReader io.Reader) (*InvocationResponse, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert this to the more natural sounding invokefunction, perhaps capitalize to invokeFunction or just invoke.

Copy link
Member

@alexellis alexellis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to see this PR put on hold and a new PR raised which simply does the one thing the original issued ask for without any additional refactoring.

The refactoring makes this hard for me to review and verify and is not necessary for the sake of the original requirement - return status, body and error instead of void.

@ivanayov
Copy link
Contributor

@Templum I'd suggest the following:

  1. Keep this, but raise a new PR as minimal as possible to cover the requirements in Update invokefunction to return headers #2
  2. Open an issue for the refactoring work, stating why you find it useful and if it's approved, you can go on with the work already done or started.

)

func TestInvoker_Invoke(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you'd like to back-port your tests to my PR that would be appreciated.

I've implemented the changes with a subscriber model that should make testing easier also.

@alexellis alexellis closed this in #8 Jan 25, 2019
@Templum Templum mentioned this pull request Jan 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants