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

feat: add fast-cgi worker #71

Open
wants to merge 1 commit into
base: version-3
Choose a base branch
from

Conversation

johnduro
Copy link
Contributor

Hey @corvus-ch ,

Here is a first implementation of fast-cgi, don't hesitate to ask for modification if you think it would be better/more consistent in an other way.

I did not touch nor add any test yet, i prefer you validate this draft before and i ll add them in another commit.

Check carefully the error handling as i'm not totally sure it is ok.

Should i add validation of the configuration ? For executable for example. And where do you see it ?

Copy link
Owner

@corvus-ch corvus-ch left a comment

Choose a reason for hiding this comment

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

Hi @johnduro,

Thanks fro your contribution. I am OK with most of it, keeping in mind that this is a work in progress. In general, I miss comments on the public functions. I have also left comments on a few things.

There is one topic we need to discuss and find an agreement. What shall be the format when sending the data to FCGI. I had planned to keep the body and the metadata separate from each other in order to prevent any strange and hard to control encoding issues. I see three options:

  1. Send the metadata separated as headers/environment variables. I have not checked if this even doable.
  2. Have body and metadata send together in one JSON document. In that case the body needs to be encoded with base64 to prevent issues.
  3. Make use multipart mime types and send the meta data as JSON document in one part and the body in a second one.

I would prefer to no longer maintain one format. The all in one JSON document is a bad candidate as it might be a lot of overhead for simpler use cases. The separation would allow to cover both simple and complex use cases without the need of using multiple formats which required to change core concepts on the implementation.

What do you think?

Regards
Christian

@@ -0,0 +1,28 @@
package factory
Copy link
Owner

Choose a reason for hiding this comment

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

I would place NewProcess directly in the worker package.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i tried to do that but then worker package must import fastcgi and exec package and these two implement worker making a circular dependency forbidden by go

)

func NewProcess(config *config.Config, logger logr.Logger) (worker.Process, error) {
if config.Worker() == "executable" {
Copy link
Owner

Choose a reason for hiding this comment

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

Use constants for the possible worker values.

)

func NewProcess(config *config.Config, logger logr.Logger) (worker.Process, error) {
if config.Worker() == "executable" {
Copy link
Owner

Choose a reason for hiding this comment

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

Personally I would prefer a switch/case construct here.

main.go Outdated
} else {
// TODO Make reject/requeue conditions configurable.
p = exec.New(e, []int{}, c.Bool("output"), ll)
// TODO Make reject/requeue conditions configurable.
Copy link
Owner

Choose a reason for hiding this comment

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

This comment needs to be kept with the call of exec.New.

}

p.PayloadMaker = p.newPayload
if config.Include() == true {
Copy link
Owner

Choose a reason for hiding this comment

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

I would like to get rid of maintaining multiple payload formats. See #59. I would prefer to have the meta data submitted as headers/environment variables and keep the body on its own.

fcgi, err := fcgiclient.Dial(p.Network, p.Address)

if err != nil {
p.Log.Info("Failed to initiate connexion to fast-cgi.")
Copy link
Owner

Choose a reason for hiding this comment

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

Keep this as one single error message.

Exchange: attributes.Exchange(),
RoutingKey: attributes.RoutingKey(),
},
Body: buffer.Bytes(),
Copy link
Owner

Choose a reason for hiding this comment

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

If the body consists of arbitrary binary data, this is likely to yield unexpected results if not broken JSON documents. See https://stackoverflow.com/questions/1443158/binary-data-in-json-string-something-better-than-base64.

Making use of a multipart mime type could also be an option.

@johnduro
Copy link
Contributor Author

johnduro commented Aug 9, 2019

Hey @corvus-ch,

Thank you for your review, i'll try to work on it next week.

For the sending format i tried to reproduce the way the data were sent previously
but i see what you mean and i think too it would be better to have a single format for the body.

  1. I think sending metadata through header/fast-cgi param would be my first choice
    but i have to check to doability as it is not obvious the lib will permit it.
    If this way works i'll send it as a json (encoded in base64 ? not mandatory i think) in a key rmq_metadata.
  2. Sending the json document like now with include would be my third and fallback choice.
  3. Sending 2 documents is doable with the lib so if the first does not work i'll go for this one.

Ok for your others comments, i'll treat them soon.

Regards

@corvus-ch
Copy link
Owner

If this way works i'll send it as a json (encoded in base64 ? not mandatory i think) in a key rmq_metadata.

Why not sending them as multiple headers? One per meta data field? No need for JSON encode and decode. The worker code can just pick the values he is interested in and ignore the others.

@johnduro
Copy link
Contributor Author

Some meta might be arrays so we will have to choose a format anyway for them and, from my point of view, i would prefer to do only one decode and maybe validation on a single json document than several.

@johnduro
Copy link
Contributor Author

Hey @corvus-ch ,

I updated the PR (i'll to be more responsive for the next steps !) with your review, tell me if it is ok and right after i'll start the tests.

For the payload i was able to pass the metadata through a json inside the header HTTP_RMQ_METADATA in the consumer which transform into rmq-metadata at the arrival.

Tell me if things are missing or not the way you'd want them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants