Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Rectovagitron
Mar 13, 2007


Grimey Drawer

Kuule hain nussivan posted:

Hello Go-thread. I'm planning my first Go-project with a couple of people and am having a hard time figuring out whether my design choices are sane or not, please help if you have the time.

The plan is to make a backend consisting of several microservices and run it off Google Cloud Run. A Kubernetes Engine would probably be a better choice, but it doesn't have a free tier and we don't want to spend money, so we decided that Cloud Run should be fine for a proof-of-concept / minimum viable product. My background is primarily in C#, so I'm used to singletons and the like. So my plan was to have my main.go file instantiate a single copy of my other classes (logger, db, etc.) and then pass pointers around. For example, my db class does some logging, so after creating an instance of the logger in main, I would then create an instance of the db class and pass a pointer of the logger to the db class, instead of creating a new instance specifically for the db class. To me, this also feels like it would mesh well with Cloud Run, because there's generally no need to create multiple instances of service classes.

Does this seem sensible? It's technically not a strict singleton, since there's nothing limiting me from creating 10,000 loggers in main. Because of this, I think trying to keep a singleton pattern going on might be a bad idea, and if someone else keeps working on the project it'll eventually lead to a situation where you have a mixed bag of a single instance being passed around as a pointer and some classes creating their own instances. Is there a way of forcing a strict singleton pattern with go? Am I overthinking this too much and should I just go gently caress it and implement what feels good to me?

Cloud Run's free tier has been great for me. I did move a service to GKE that had some larger memory requirements, but Cloud Run seems to work for everything else.

For loggers, I honestly use package level variables, as they tend to be safe for concurrent use, and don't impact my overall application design very much. For other things, like DB connections, or other service connections, I typically instantiate a Server struct, and provide those connections or configuration to it in the main function. This helps you structure your handlers in a way where it's easier to plug in a fake database for testing, or a fake/in-memory database or service for local development. I find it helps me keep a separation of concerns between different objects in my app.

In general, instantiating things in Go is extremely cheap, so I take advantage of that unless I want persistent connections, which is frequently the case for databases and other services.

If you're new to Go, one of the first things that helped me a lot when learning how to work with the language was that in general, functions should return pointers to structs, and accept interfaces as arguments. Interface definitions should go by where they're consumed, not where they're produced. This will help you keep a good contract at the call-site, and make it easier to change implementations without breaking consumers. As a bonus, it makes things really easy to fake out for unit testing, helping you avoid integration tests except where necessary.

Finally, always run tests with the race detector on, and use go vet. Have fun.

Adbot
ADBOT LOVES YOU

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply