-
Notifications
You must be signed in to change notification settings - Fork 57
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
Unable to use vendoring with golang-http #78
Comments
@LucasRoesler do you see any other variations for potential solutions? |
I think 3 would be the best solution. Seems I would need to change all of my functions :(. I personally don't use vendoring at all. I prefer to simply name modules in my functions or create and import my own modules to use them. |
Thanks for the input Billy. If we went ahead with 3) and didn't give it a brand new name, then there are a couple of scenarios: A) The change for all your functions could potentially be done with a search and replace across all files in VSCode. B) You could also use the tag or SHA of before we make the change: configuration:
templates:
- name: golang-http
source: https://github.com/openfaas/golang-http-template#VERSION/TAG/SHA One other option for 3) is for us to keep maintaining (for 6 mo?) a branch for people who don't use private Go modules / repos, that they can access via: |
i will just make the changes whenever needed and roll the new ones out. Maintaining a classic may be a good idea but everyone has to change anyway since it's a core go problem. With enough notice and planned upgrade it shouldn't be an issue. |
Personally I have no preference between Only thing I would currently change about @alexellis I made a PoC repo for a rework which makes the major build change of moving This iteration provides a https://github.com/kevin-lindsay-1/openfaas-golang-http-rework |
Hi Kevin, The approach where the function has a main is 4). It would not duplicate the entry point code as per your PoC, but reference a separate repository, i.e. import repo/with/sdk
func handler(sdk.Request) sdk.Response {
}
main() {
sdk.Serve(handler)
} If you don't want to buffer the request into memory, and you have a large request, then you should use golang-middleware instead. You don't use WithContext when using golang-middleware, you can just use the context from the http.Request object. For 3), you can try out my template that uses an interface, it works for your use-case of vendoring private code whilst continuing to use the Request / Response style we are used to seeing in functions. Clone this repo, and try building the withlogrus example. You'll see that it looks very much like what you're using today. https://github.com/alexellis/golang-http-template golang-middleware is more like a micro service handler Alex |
Good points, and yeah it sounds like our use cases have expanded a little, and it seems like our team is growing out of This pushes me in favor of "2", I'll probably be refactoring our stuff to use middleware, just so that we aren't using multiple templates when we don't need to, lowering our surface area for bugs internally.
Yes, I agree, I think it would have prevented the error I was seeing with *technically, it's munged, so it's not actually 2 when the build is done. |
I found a hacky way to build but it is essentially localizing the req/res models(to be honest, I wanted to remove this intermediary a while ago by including that file into golang-http templates), I think golang-http template can exist but we need to localize github.com/alexellis/templates-sdk/go-http into that repository if that makes sense. Example can be found here but also you may or may not be able to build successfully because "handler/handler" is not a package for the hello function |
Hi @mrwormhole that's similar to how the "go" classic template works. For some reason I can't remember, we moved away from that to a separate dependency. It could have been about intellisense, IDEs or unit-testing. So this may (with additional validation) be an alternative to the interfaces that I've suggested above. Alex |
I can understand totally why it was moved to a separate place but for golang-http template to work with go.work, I feel like we need to localize this into golang-http repository, the impact is changing all the docs for faasd examples but it will probably not impact anywhere else if go-http is used somewhere else outside of these templates. since golang-http has its own mod file with "handler" I know intellisense won't work but we can create a go.mod file at the top perhaps and remove go.work from the highest level? need to confirm with @LucasRoesler if there are no solutions, I guess we wait but I am pretty sure they won't support go.work with -mod=vendor flag while modules are on. The problem is workspaces don't support partial dependency fetching, if we have a single go.mod and we have dependencies there and we have a single vendor folder and some dependencies don't exist in that vendor folder, Go is smart enough to download missing dependencies and use vendor for existing dependencies, this doesn't happen when you have a go.work based project with multiple submodules. Meaning that it either uses vendors of every subfolder or goes the full download of every subfolder mode. (this ruins the private repo users experience for this specific template) Technically, we can remove golang-http from templates and go home or provide golang-http without workspaces(shell scripts were dreaded for the end users but it worked for this golang-http template) but I do feel like there is a value there for beginners and old existing projects and I think go.work is awesome use-case even though it conflicts with build phase of templates. Needs a discussion with @LucasRoesler |
I think after a lot of time thinking on this, that just reverting to the previous behavior before workspaces makes the most sense. I am not a purist on this, if a little bash makes the template work smoothly for 99% of use-cases, then let's use some bash. Especially because the bash script is just calling some Originally, I thought the workspaces would allow us to really remove the bash scripts, but they don't seem to work as expected. I have prepared a branch for re-adding the bash scripts and tested it against my golang template sandbox https://github.com/LucasRoesler/golang-http-template-examples it seems to behave well. But I could be missing an important test case, so please take a look and let me know. Here is the branch I created https://github.com/openfaas/golang-http-template/compare/master...LucasRoesler:feat-revert-to-bash-scripts?expand=1 As an aside, but something I saw in the conversation above. In general, I would expect most projects to use only one or the other template, not a mix of both. Just for code consistency in the project to ease the developer experience, I would avoid mixing and matching templates within a project. Within an organization, sure use whichever fits best for your project, but stick with just one for a project. |
@LucasRoesler @alexellis nothing is wrong with working scripts, it is just maintenance overhead sometimes(better if it was possible to abstract away), I think go.work use case in middlewares is a top notch use case of workspaces in this project It worked perfectly for that template and it was great thinking on that one, so I guess it is better if we only tweak the non-working one with old working scripts? |
It looks like we have three main options for going forward.
I'd be interested in speed differences between 2 and 3 for an uncached container build, or one with Alex |
I did follow up on number 3 after giving tons of thoughts; I have followed up Lucas's feat-revert-to-bash-scripts branch and opened up this #81 |
I've hacked a bit on my fork of the template: https://github.com/alexellis/golang-http-template Then this example shows a vendored public dependency https://github.com/alexellis/golang-http-template/tree/master/withlogrus |
I have checked gohttp.Request and gohttp.Response, I can't say I like this approach. For example, if I want to test the handler for integration tests(checking gohttp.Responses and errors without mocks), I have to use NewFunctionRequest from http Request struct for my testdata in every integration test. The second reason I have is I think noone will have time to update old articles that have done demonstrations on golang-http-template(because most nodejs background beginner people prefer something non-std way and keeping things same would make adoption easier for them and they get less confused while learning). The third reason is interface actually makes benchmarks slower and I know I have to prove this later because my assumption was based on this (https://twitter.com/badamczewski01/status/1421399041699635202) I don't think this is gonna affect any customers because noone cares about nanoseconds I would rather prefer to keep shell scripts(yes, I do still hate shell scripts but I would side with backward compatibility over maintainability) for the first template(golang-http-template) and put a non-preferred way and not maintain golang-http template anymore but that's just my thought. It is cool for beginners to look at the same thing that doesn't make them use interfaces at first sight. (often times beginners abuse the heck out of interfaces in my experience) |
Tested with a private Go module which was vendored, setting GO111MODULE: off in build_args in stack.yml I also created a nested package called pkg and referenced it as "handler/function/pkg" from handler.go which worked as expected. Closes: #78 Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
Tested with a private Go module which was vendored, setting GO111MODULE: off in build_args in stack.yml I also created a nested package called pkg and referenced it as "handler/function/pkg" from handler.go which worked as expected. Closes: #78 Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
Tested with a private Go module which was vendored, setting GO111MODULE: off in build_args in stack.yml I also created a nested package called pkg and referenced it as "handler/function/pkg" from handler.go which worked as expected. Closes: #78 Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
Tested with a private Go module which was vendored, setting GO111MODULE: off in build_args in stack.yml I also created a nested package called pkg and referenced it as "handler/function/pkg" from handler.go which worked as expected. Closes: #78 Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
Tested with a private Go module which was vendored, setting GO111MODULE: off in build_args in stack.yml I also created a nested package called pkg and referenced it as "handler/function/pkg" from handler.go which worked as expected. Closes: #78 Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
Why do you need this?
I need to be able to use vendoring with the golang-http template because it is how I get private Go code into my functions.
Expected Behaviour
This should work without error, when using a vendor folder and any other stack.yml flags or build-args required:
Current Behaviour
List All Possible Solutions and Workarounds
golang-http-vendoring
that only works with vendoringFor 4), the function's handler owns the main() entrypoint instead of the hidden underlying code, and calls a utility method to set up the HTTP server etc.
For 3), the code would end up looking like this for a handler:
(this can be compared to the second code sample to see what's different)
What is your preferred solution?
I like 3) and to lessen its impact to existing users, we could consider promoting golang-http into the primary community templates repository and deprecating the one we use here.
Alternatively, we could call it "go-http1.18
or
golang-http1.18as a new template, with
golang-http1.19` and so on coming after that.Steps to Reproduce (for bugs)
Edit
withlogrus/handler.go
:Then edit
withlogrus.yml
, adding:Then try a build:
The text was updated successfully, but these errors were encountered: