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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃 [Question]: zero allocation - why is this any different from how Chi or others behave? Can you document an example of what you mean? #3052

Open
3 tasks done
unusualevent opened this issue Jun 30, 2024 · 8 comments

Comments

@unusualevent
Copy link

Question Description

How are people re-using ctx? I don't really get that. I thought the ctx was just for DB pools that give you individual access to the DB, or for the cancellation of the program. Aren't most function contexts supposed to be local variables only (or at least dependent on a specific session?)

I'm not sure why but that throws me for a complete loop having it at the beginning of the docs. What makes code written for Fiber different from code written for Chi or similar?

Code Snippet (optional)

package main

import "github.com/gofiber/fiber/v3"
import "log"

func main() {
  app := fiber.New()

  // An example to describe the question

  log.Fatal(app.Listen(":3000"))
}

Checklist:

  • I agree to follow Fiber's Code of Conduct.
  • I have checked for existing issues that describe my questions prior to opening this one.
  • I understand that improperly formatted questions may be closed without explanation.
Copy link

welcome bot commented Jun 30, 2024

Thanks for opening your first issue here! 馃帀 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

@gaby
Copy link
Member

gaby commented Jun 30, 2024

@unusualevent The context object is only valid during the handler, once you return from the handler the context is released.

This is explain in detail on the documentation: https://docs.gofiber.io/#zero-allocation

@unusualevent
Copy link
Author

Yeah, I'm saying the documentation makes it more confusing.

@gaby
Copy link
Member

gaby commented Jun 30, 2024

@unusualevent Here鈥檚 a simplified comparison:

Fiber:

  • Context values are mutable and reused across requests by default to enhance performance. This an inherited behavior from fasthttp which Fiber is based on.
  • You need to make copies of these values if you want to use them outside the handler to avoid unexpected changes.

net/http based frameworks like chi, echo:

  • Context values are immutable by default.
  • You can safely keep references to these values outside the handler without worrying about them changing.

You can make Fiber's context immutable as explain in the documentation through fiber.Config{immutable: True}

@unusualevent
Copy link
Author

Maybe I'm just dense. At least you said it in a succinct way. How would someone solve a problem differently without immutable context, compared to how they're used to doing it in net/http?

@gaby
Copy link
Member

gaby commented Jun 30, 2024

@unusualevent As stated in the documentation:

app := fiber.New(fiber.Config{
	Immutable: true,
})

You can also make a single value immutable using the util functions:

app.Get("/:foo", func(c *fiber.Ctx) error {
	// Variable is now immutable
	result := utils.CopyString(c.Params("foo")) 
})

The utils have both CopyString and CopyBytes for this purpose.

@gaby
Copy link
Member

gaby commented Jun 30, 2024

Any suggestions of what we should add are welcome. The wording in the docs could use some help.

@sixcolors
Copy link
Member

sixcolors commented Jul 1, 2024

From the fasthttp documentation (which Fiber is built upon):

fasthttp might not be for you!

fasthttp was designed for some high-performance edge cases. Unless your server/client needs to handle thousands of small to medium requests per second and requires a consistent low millisecond response time, fasthttp might not be for you. For most cases, net/http is much better as it's easier to use and can handle more situations. In most scenarios, you won't even notice the performance difference.

Given this context, Fiber inherits these high-performance characteristics and trade-offs. The reuse of the ctx object in Fiber is a deliberate design choice to maximize performance by reducing allocations. This approach is beneficial in high-throughput scenarios but requires developers to be mindful of the mutable nature of the context.

For most developers using ctx values within the handler, this design choice won't cause issues. However, for those just starting with more complex systems or applications and not fully grasping the implications, it can be challenging. In such cases, a net/http-based framework might be a more straightforward option.

The immutable setting in Fiber, while available, can reduce some of the performance benefits that Fiber offers. At that point, net/http frameworks may provide similar performance without the added complexity of an immutable ctx and with the added advantage of being more widely used and supported.

Fiber and its base fasthttp are tailored for specific high-performance scenarios. For many use cases, especially for developers seeking simplicity and robust community support, a net/http-based framework might be the better choice. However, for those needing extreme performance optimizations, Fiber remains a powerful and efficient option.

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

No branches or pull requests

3 participants